[bzoj1045][HAOI2008] 糖果传递【构造】

【题目链接】
  http://www.lydsy.com/JudgeOnline/problem.php?id=1045
【题解】
  记 X[i] X [ i ] 为从第 i i 堆向第 i+1 i + 1 堆转移的数量。(第 n n 堆转移到 1 1
  那么有 a[i]X[i]+X[i1]=average a [ i ] − X [ i ] + X [ i − 1 ] = a v e r a g e
   X[i]=a[i]+X[i1]average X [ i ] = a [ i ] + X [ i − 1 ] − a v e r a g e
  移项得: X[1]=a[1]+X[n]avarage X [ 1 ] = a [ 1 ] + X [ n ] − a v a r a g e
       X[2]=a[2]+X[1]avarage X [ 2 ] = a [ 2 ] + X [ 1 ] − a v a r a g e
       =a[2]+a[1]+X[n]2average = a [ 2 ] + a [ 1 ] + X [ n ] − 2 ∗ a v e r a g e
     X[i]=ij=1a[i]X[n]iavarage X [ i ] = ∑ j = 1 i a [ i ] − X [ n ] − i ∗ a v a r a g e
  记 S[i]=ij=1a[i]iavarage S [ i ] = ∑ j = 1 i a [ i ] − i ∗ a v a r a g e
 有 X[i]=S[i]X[n] X [ i ] = S [ i ] − X [ n ]
  ans=ni=1|X[n]S[i]| a n s = ∑ i = 1 n | X [ n ] − S [ i ] |
 当 X[n] X [ n ] S[i] S [ i ] 中位数的时候 ans a n s 取到最小值。
 复杂度 O(nlog2n) O ( n l o g 2 n )

/* --------------
    user Vanisher
    problem bzoj-1045 
----------------*/
# include 
# define    ll      long long
# define    inf     0x3f3f3f3f
# define    N       1000100
using namespace std;
ll read(){
    ll tmp=0, fh=1; char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
    while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
    return tmp*fh;
}
ll a[N],cnt,n,s[N],ans,now;
int main(){
    n=read();
    for (ll i=1; i<=n; i++)
        a[i]=read(), cnt+=a[i];
    cnt=cnt/n;
    for (ll i=1; i<=n; i++)
        s[i]=a[i]-cnt+s[i-1];
    sort(s+1,s+n+1);
    now=s[(1+n)/2];
    for (ll i=1; i<=n; i++)
        ans=ans+abs(s[i]-now);
    printf("%lld\n",ans);
    return 0;
}

同[bzoj1465][bzoj3293]

你可能感兴趣的:(【构造】)