題目鏈接:Tweetuzki 愛軍訓
如果直接去做是很複雜的。
我們假設全部都是第一次出隊,那麼我們可以發現,如果第i個改成第二次出隊,那麼答案增加:
(n-i)*w-sum(i+1,n)
然後我們從後往前找第二次出隊的,我們可以發現後面是否出隊和之前第二次出隊的是沒有影響的。
AC代碼:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
int n,res,sum,a[N],vis[N],cnt;
vector<int> ans;
signed main(){
cin>>n;
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=n;i>=1;i--){
if((n-i)*a[i]>=sum) vis[i]=1;
sum+=a[i];
}
for(int i=1;i<=n;i++) if(!vis[i]) res+=(++cnt)*a[i],ans.push_back(a[i]);
for(int i=n;i>=1;i--) if(vis[i]) res+=(++cnt)*a[i],ans.push_back(a[i]);
cout<<res<<endl;
for(int i:ans) printf("%lld ",i);
return 0;
}