Atcoder Grand Contest 010 B - Boxes 差分

B - Boxes

题目连接:

http://agc010.contest.atcoder.jp/tasks/agc010_b

Description

There are N boxes arranged in a circle. The i-th box contains Ai stones.

Determine whether it is possible to remove all the stones from the boxes by repeatedly performing the following operation:

Select one box. Let the box be the i-th box. Then, for each j from 1 through N, remove exactly j stones from the (i+j)-th box. Here, the (N+k)-th box is identified with the k-th box.
Note that the operation cannot be performed if there is a box that does not contain enough number of stones to be removed.

Input

1≦N≦105
1≦Ai≦109
The input is given from Standard Input in the following format:

N
A1 A2 … AN

Output

If it is possible to remove all the stones from the boxes, print YES. Otherwise, print NO.

Sample Input

5
4 5 1 2 3

Sample Output

YES

Hint

题意

给你n个数,你可以操作任意次,每次操作你可以选择一个数,使得离这个数距离为i的数-i。

问你最后是否能够使得所有数都变成0.

题解:

每次操作会减去1+2+....+n=n(n+1)/2,所以至少sum%(n(n+1)/2)==0

满足这个条件之后,我们发现是一个等差数列递减的,那么我们差分一下,就变成全部减一了。但是!最后一个数和第一个数之间的差值,却增加了(-(n-1)),这个推一下就知道了。

那么差分后的d[i]=a[i+1]-a[i],必须满足d[i] − (k − x) + (n − 1)x = 0,其中k为总共操作次数,x为在这个位置的操作次数,化简后得到k-d[i]=nx,那么我们只需要check(k-d[i]%n==0)就好了。

智商题……

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int n;
long long a[maxn],b[maxn],sum;
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%lld",&a[i]),sum+=a[i];
    long long t=1ll*n*(n+1)/2;
    if(sum%t){
        cout<<"NO"<<endl;
        return 0;
    }
    long long cnt = sum/t;
    for(int i=0;i<n;i++){
        b[i]=(a[(i+1)%n]-a[i]-cnt);
    }
    bool flag = true;
    for(int i=0;i<n;i++){
        if(b[i]>0||(-b[i])%n)
            flag = false;
    }
    puts(flag?"YES":"NO");
}
posted @ 2017-02-04 22:49  qscqesze  阅读(493)  评论(0编辑  收藏  举报