题目:
题意:
给出 n n n个人的能量,间隔为 k k k的两个人才能传递能量,问最少要用多少次才能使所有人的能量相等
分析:
我们可以与洛谷上的糖果传递进行类比,那道题的间隔是 0 0 0,但在这里是 k k k
所以我们可以以 i i i这个点开始暴力求出一个环,环上的点都恰好间隔为 k k k,这样一来单独看环的话每个点的间隔都是 0 0 0了
我们就直接按照糖果传递的方法来跑
代码:
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<vector>
#define LL long long
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){
if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){
d=d*10+s-'0';s=getchar();}
return d*f;
}
LL tf[500005],x[500005],y[500005],a,xx[500005];
int main()
{
LL n=read(),k=read()+1,ans=0;
for(LL i=1;i<=n;i++) x[i]=read(),a+=x[i];
a/=n;
for(LL i=1;i<=n;i++)
{
if(tf[i]) continue;
LL len=0,j=i;
while(!tf[j])
{
tf[j]=1;y[++len]=x[j];j+=k;
j=(j-1)%n+1;
}
for(LL i=1;i<=len;i++) xx[i]=xx[i-1]+y[i]-a;
sort(xx+1,xx+1+len);
LL e;
if(len&1) e=xx[len/2+1];
else e=(xx[len/2]+xx[len/2+1])/2;
for(LL i=1;i<=len;i++) ans+=abs(xx[i]-e);
}
cout<<ans;
return 0;
}