如果不是圈,可以从
1
∼
n
\mathfrak{1\thicksim n}
1∼n递推
规定一个标准传递方向,可以把顺方向的传递记作正权,反方向记作负权。
每一步把
t
e
m
p
\mathfrak{temp}
temp(初始化为
0
\mathfrak{0}
0)累加上
a
i
−
a
‾
\mathfrak{a_i-\overline{a}}
ai−a,
a
n
s
\mathfrak{ans}
ans(初始化为
0
\mathfrak{0}
0)累加上
t
e
m
p
\mathfrak{temp}
temp。
(以上均为口胡,没有找到题目,不保证正确性)
现在问题到了环上就不好这么想了。
假设第
i
\mathfrak{i}
i个人给第
j
\mathfrak{j}
j个人传递了
x
i
,
j
\mathfrak{x_{i,j}}
xi,j?
实际上没有必要,因为一个人直接地只会传给一个人
设第
i
\mathfrak{i}
i个人给第
(
i
  
m
o
d
  
n
)
+
1
\mathfrak{(i\;mod\;n)+1}
(imodn)+1个人传递了
x
i
\mathfrak{x_i}
xi(反过来也行)
有:
a
n
s
=
∑
i
=
1
n
∣
x
i
∣
\mathfrak{ans=\sum\limits_{i=1}^n{|x_i|}}
ans=i=1∑n∣xi∣
这还不够。如果规定了这样的方向,那么有:第
i
\mathfrak{i}
i个人最后的值为
a
i
−
x
i
+
x
i
−
1
=
a
‾
\mathfrak{a_i}-\mathfrak{x_i}+\mathfrak{x_{i-1}}=\mathfrak{\overline{a}}
ai−xi+xi−1=a
(不单独给
n
→
1
\mathfrak{n}\to 1
n→1分类了,知道就好)
然后这个可以列
n
−
1
\mathfrak{n-1}
n−1个式子消掉
n
−
1
\mathfrak{n-1}
n−1个
x
\mathfrak{x}
x
它们都可以表示为形如:
x
j
=
x
∀
i
+
ξ
j
x_j=\mathfrak{x_{\forall i}+\xi_j}
xj=x∀i+ξj
a 1 − x 1 + x n = a ‾ ⋯ x 1 = a 1 + x n − a ‾ = a 1 + x n − a ‾ \mathfrak{a_1-x_1+x_n=\overline{a}\quad\cdots\quad x_1=a_1+x_n-\overline{a}=a_1+x_n-\overline{a}} a1−x1+xn=a⋯x1=a1+xn−a=a1+xn−a
a 2 − x 2 + x 1 = a ‾ ⋯ x 2 = a 2 + x 1 − a ‾ = a 1 + a 2 + x n − 2 a ‾ \mathfrak{a_2-x_2+x_1=\overline{a}\quad\cdots\quad x_2=a_2+x_1-\overline{a}=a_1+a_2+x_n-2\overline{a}} a2−x2+x1=a⋯x2=a2+x1−a=a1+a2+xn−2a
a 3 − x 3 + x 2 = a ‾ ⋯ x 3 = a 3 + x 2 − a ‾ = a 1 + a 2 + a 3 + x n − 3 a ‾ \mathfrak{a_3-x_3+x_2=\overline{a}\quad\cdots\quad x_3=a_3+x_2-\overline{a}=a_1+a_2+a_3+x_n-3\overline{a}} a3−x3+x2=a⋯x3=a3+x2−a=a1+a2+a3+xn−3a
    ⋮ \qquad\qquad\qquad\qquad\;\,\vdots ⋮
⋯      ​ ⋯ x n − 1 = x n − ( n − 1 ) a ‾ + ∑ i = 1 n − 1 a i \qquad\quad\cdots\quad\;\;\ \!\quad\quad\cdots\quad\mathfrak{x_{n-1}=x_n-(n-1)\overline{a}+\sum\limits_{i=1}^{n-1}a_i} ⋯ ⋯xn−1=xn−(n−1)a+i=1∑n−1ai
a
n
s
=
∣
x
n
∣
+
∑
i
=
1
n
−
1
∣
x
n
−
i
a
‾
+
∑
j
=
1
i
a
j
∣
\mathfrak{ans=|x_n|+\sum\limits_{i=1}^{n-1}|x_n-i\overline{a}+\sum\limits_{j=1}^i}a_j|
ans=∣xn∣+i=1∑n−1∣xn−ia+j=1∑iaj∣
由此可得要使
a
n
s
\mathfrak{ans}
ans最小就得让
x
n
\mathfrak{x_n}
xn满足某种条件
注意到
a
n
s
=
∑
i
=
1
n
∣
x
n
−
F
i
∣
\mathfrak{ans=\sum\limits_{i=1}^n{|x_n-F_i|}}
ans=i=1∑n∣xn−Fi∣要使
a
n
s
\mathfrak{ans}
ans最小
所以取中位数。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
using namespace std;
int n;
long long x,pre=0,a[1000005]={},aver=0;
long long delta[1000005]={},midpos,deltamid,ans=0;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%lld",&a[i]),aver+=a[i];
aver/=n;
for(int i=1;i<=n;++i)
{
pre+=a[i];
if(i<n)delta[i]=i*aver-pre;
}
sort(delta+1,delta+n);
deltamid=delta[1]+delta[n]>>1;
midpos=(n&1)?delta[n+2>>1]:((abs(deltamid-delta[n>>1])<abs(deltamid-delta[n+2>>1]))?(n>>1):(n+2>>1));
for(int i=1;i<n;++i)ans+=abs(delta[i]-delta[midpos]);
printf("%lld",abs(delta[midpos])+ans);
return 0;
}