ABC 313 G 题解
Solution
简单题。我们不妨把每个位置看做一座小山,石子的数量是小山的高度。
那么每次只有两种操作:把所有山的山头削低一格;把所有山的山头升高一格。注意不能是负数。
我们发现,操作一有点类似“拉平效应”,如果两座山头都比较矮,那么经过几次操作一之后他们高度都变成了零,之后也就一直一样了。
因此我们会设一个阈值
我们应当指出,只要往下减之后所有山高度的总数小于等于原来的高度,那么一定有解。因为你可以执行
我们枚举填平层的上面那一层,这一层及上方的总数为
然后你发现
代码:
#include<bits/stdc++.h>
#define int long long
#define ffor(i,a,b) for(int i=(a);i<=(b);i++)
#define roff(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int MAXN=2e5+10,MOD=998244353;
int n,tot,h[MAXN],ans;
map<int,int> mp;
int f(int a,int b,int c,int n) {
if(n<=0) return 0;
int A=(a%c+c)%c,B=(b%c+c)%c;
if(A!=a||B!=b) {
int aa=(a-A)/c%MOD,bb=(b-B)/c%MOD,ans0=(bb*n%MOD+n*(n+1)/2%MOD*aa)%MOD;
return (ans0+f(A,B,c,n))%MOD;
}
if(a==0) return (b/c)%MOD*n%MOD;
int m=(a*n+b)/c,ans0=m%MOD*n%MOD;
return ((ans0-f(c,-b-1,a,m))%MOD+MOD)%MOD;
}
signed main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n; ffor(i,1,n) cin>>h[i],mp[h[i]]++,tot+=h[i];
mp[0]++; int pre=0,cnt=0;
for(auto it=--mp.end();it!=mp.begin();it--) {
auto It=it; It--;
cnt+=it->second;
if(cnt==n) break;
// cout<<-cnt<<' '<<tot-pre<<' '<<n<<' '<<it->first-It->first<<' '<<f(-cnt,tot-pre,n,it->first-It->first)<<'\n';
ans=(ans+it->first-It->first+f(-cnt,tot-pre,n,it->first-It->first))%MOD;
pre=pre+(it->first-It->first)*cnt;
}
ans+=tot/n+1;
ans=(ans%MOD+MOD)%MOD;
cout<<ans;
return 0;
}