题意:给定N个围成一圈的数,重复进行下述操作:
挑选第i个数,从i+1转一圈回到i,依次减去1到N。
问是否存在一种操作使得最后整圈的数全为0。
解法:
将该过程倒着来看,就是每轮选择第i个数,从i+1转一圈回到i,依次加上1到N,将该操作设为操作1。问最后能否加到给定数列。
另d[i]=a[i]-a[i-1],即考虑前数与后数之间的差,会发现,每次进行操作1时,差分的改变要么+1,要么-N+1,且两种情况里都有+1。故将查分减去s(操作的轮数),即处理掉+1的影响后。-N出现的次数恰为操作的轮数。编程验证一下上述关系式是否都满足就行了,
#include <cstdio>
const int maxn=100005;
long long tot,n,r,a[maxn],t;
void solve() {
if (n==1) {
puts("YES");
return;
}
if ((tot<<1)%(n*(n+1))) {
puts("NO");
return;
}
r=tot/(n*(n+1)/2);
for (int i=0;i<n;++i) {
a[i]-=r;
if (a[i]%n||a[i]>0) {
puts("NO");
return;
}
t+=a[i]/(-n);
}
puts(t==r?"YES":"NO");
}
int main()
{
scanf("%lld",&n);
for (int i=1;i<=n;++i) {
scanf("%lld",&a[i]);
tot+=a[i];
a[i-1]=a[i]-a[i-1];
}
a[0]=a[0]-a[n];
solve();
return 0;
}