题意
n盒排成一列的糖果盒,第
i盒有
ai个糖果
每次可以取出某一盒一颗糖果放到相邻的糖果盒里
问使得所有盒子的里的糖果数均能被某个
k(k>1)整除的最少移动次数
题解
设糖果总数的
Sum(显然
Sum=1无解)
符合条件的
k一定满足
k∣Sum
考虑对于一个
k如何求解最少的移动次数
首先肯定要将所有的
ai对
k取余
对于一个
ai可以将
ai颗糖果全部向后挪,于是
ai+1=(ai+1+ai)modk
也可以从后面挪
k−ai颗糖果到
ai上,于是
ai+1=ai+1−(k−ai)≡ai+1+aimodk
设
Si=∑k=1iaimodk,那么
Ans=∑i=1nmin(Si,k−Si)
通过上面可以发现如果如果
k1∣Sum,k2∣Sum,且
k=k1k2∣Sum
那么
k的答案一定不会比
k1,k2优,所以只需要枚举
Sum的质因子即可
题目当中
Sum≤1012,而
2×3×5×…×37>1012,所以计算次数不会太多
时间复杂度为
O(n×Sum质因子个数
+Sum
)
using ll=long long;
inline ll Calc(ll p){
ll Cnt=0,Tmp=0;
for(int i=1;i<=n;++i)
Cnt=(Cnt+a[i])%p,Tmp+=min(Cnt,p-Cnt);
return Tmp;
}
inline void Sol(){
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",a+i),Sum+=a[i];
if(Sum<2)
return(void)puts("-1");
Ans=-1ull>>1;
for(int i=2;(ll)i*i<=Sum;++i)
if(Sum%i==0){
while(Sum%i==0)Sum/=i;
Ans=min(Ans,Calc(i));
}
if(Sum>1)
Ans=min(Ans,Calc(Sum));
printf("%d\n",Ans);
}