题目大意
有一个环,环上有一些数,求分成i份,每份要连续,对于每个分成i份的情况求每一份的数的和gcd起来最大是多少。
解题思路
我们发现答案一定是所有数和的约数,这不会很大,找出约数后求模约数的前缀和,有多少个相同就可以分成多少份。
code
using namespace std;
int const maxn=2000,size=50000;
int n;LL s[maxn+10],b[10],ans[maxn+10],h[size+10],cnt[size+10],pos[maxn+10];
int hash(LL x){
int pos=x%size;
for(;h[pos]&&(h[pos]!=x);pos=(pos==size-1)?0:pos+1);
return pos;
}
int main(){
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
scanf("%d",&n);int a;
fo(i,1,n)scanf("%d",&a),s[i]=s[i-1]+a;
int mx=sqrt(s[n]);
fo(i,1,mx)
if(s[n]%i==0){
b[1]=i;b[2]=s[n]/i;
fo(ii,1,2){
fo(j,1,n){
pos[j]=hash(s[j]%b[ii]);
h[pos[j]]=s[j]%b[ii];
cnt[pos[j]]++;
ans[cnt[pos[j]]]=max(ans[cnt[pos[j]]],b[ii]);
}
fo(j,1,n)h[pos[j]]=cnt[pos[j]]=0;
}
}
fo(i,1,n)printf("%lld\n",ans[i]);
return 0;
}