☆数列(AGC010B - Boxes)
atcoder.jp
yutaka1999さんの問題は面白いなあ(個人的には難しいですが…)
一回の操作で、選んだ箱からN 個、他の箱から1,2,3...N-1個取る。
☆1回の操作で取られる石の個数は1/2*N(N+1)なので、何回操作を行うべきなのかがわかる(または操作によって達成できないことがわかる)。x回数行うとする。
$A_2-A_1$を$B_1$、...$A_1-A_N$を$B_N$とする。
一回の操作で、iを選んだとすると、$B_i$のみ-N+1が加算され、それ以外の$B_j$には1が加算される。
$B_1$をx回の操作で実現するためには、何回$B_1$に$1$を加算するのか計算できる。
y回とすると、$y+(-N+1)(x-y)=B_1$なので、$y=\frac{B+(N-1)x}{N}$で求められる(または実現できないことがわかる。)
これをN個について行い、矛盾がなければいい。具体的には、全てのyがx以下であり、yの合計がx*(N-1)であれば良い。
これによって達成できるか達成できないかがわかる。
long long 的な何かで2回WA
全部longlongにした方がいいですね
#include<cstdio> #include<math.h> #include<algorithm> #include<vector> #include<queue> #include<string> #include<set> #include<cstring> using namespace std; #define rep(i,n) for(int i=0;i<n;i++) #define INF 1001001001 #define LLINF 1001001001001001001 #define mp make_pair #define pb push_back #define LLIandI pair<long long int , int> #define ll long long long long int A[100004]; long long int B[100004]; ll int N; long long sum=0; int main(){ scanf("%lld",&N); rep(i,N){ scanf("%lld",&A[i]); if(i>0)B[i-1]=A[i]-A[i-1]; sum+=A[i]; } B[N-1]=A[0]-A[N-1]; long long int X; if((2*sum)%(N*(N+1))==0){ X=(long long int)(2*sum/(N*(N+1))); }else{ printf("NO\n");return 0; } long long int ysum=0; rep(i,N){ ll int y=(ll int)((B[i]+(N-1)*X)/N); if((B[i]+(N-1)*X)%N==0&&y<=X){ ysum+=y; }else{ printf("NO\n");return 0; } } if(ysum==X*(N-1)){ printf("YES\n");return 0; } printf("NO\n");return 0; }