BZOJ3293_分金币_KEY
设x[i]表示i+1向i传的糖果数,x[n]表示1向n传的糖果数,a'=(a[1]+...a[N])/N
a[1]+x[1]−x[n]=a'
a[2]+x[2]−x[1]=a'
a[3]+x[3]−x[2]=a'
⋯⋯
a[n−1]+x[n−1]−x[n−2]=a'
a[n]+x[n]−x[n−1]=a'
把式子变形:
x[1]=a'−a[1]+x[n]
x[2]=a'−a[2]+x[1]=2∗a'−a[2]−a[1]+x[n]
x[3]=a'−a[3]+x[2]=3∗a'−a[3]−a[2]−a[1]+x[n]
⋯⋯
x[n−1]=a'−a[n−1]+x[n−2]=(n−1)∗a'−∑n−1i=1a[i]+x[n]
x[n]=n∗a'−∑ni=1a[i]+x[n]=0+x[n]
设s[i]=∑a[i]−i∗a',则:
ans=∑∣x[i]∣ =∑∣s[i]−x[n] ∣
所以当x[n]为{s[1],s[2],...,s[n]}的中位数时答案最小
code:
/************************************************************** Problem: 3293 User: yekehe Language: C++ Result: Accepted Time:104 ms Memory:2480 kb ****************************************************************/ #include <cstdio> #include <algorithm> using namespace std; char tc() { static char fl[100000],*A=fl,*B=fl; return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++; } long long read() { char c;while(c=tc(),(c<'0'||c>'9')&&c!='-'); long long x=0,y=1;c=='-'?y=-1:x=c-'0'; while(c=tc(),c>='0'&&c<='9')x=x*10+c-'0'; return x*y; } const int MAXN=100005; long long N,a[MAXN],sum[MAXN],w,ans,K; int i; int main() { // freopen("x.txt","r",stdin); N=read();for(i=1;i<=N;i++)a[i]=read(),w+=a[i]; w=w/N;for(i=1;i<=N;i++)sum[i]=sum[i-1]+a[i]-w; sort(sum+1,sum+N+1);for(K=sum[N+1>>1]+sum[(N>>1)+1]>>1,i=1;i<=N;i++)ans+=abs(K-sum[i]); printf("%lld",ans); return 0; }