Description
小A有一个环,环上有n个正整数。他有特殊的能力,能将环切成k段,每段包含一个或者多个数字。对于一个切分方案,小A将以如下方式计算优美程度:
首先对于每一段,求出他们的数字和。然后对于每段的和,求出他们的最大公约数,即为优美程度。
他想通过合理地使用他的特殊能力,使得切分方案的优美程度最大。
输出n行,第i行表示切成i段时的最大优美程度。
对于100%的数据,n<=2000,1<=ai<=50000000(5e7)
Analysis
思路非常好
本题解仅给出一个方向,剩余的完全可以自己思考出来
一个显然的性质:所有的答案都是∑ni=1a[i]的因数,且答案不上升
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int N=2005,mo=5017;
int n,m;
ll a[N],b[5010],h[mo],g[mo],f[N],ans[N];
ll hash(ll x)
{
ll pos=x%mo;
while(h[pos] && h[pos]!=x) pos=(pos+1)%mo;
return pos;
}
int main()
{
ll s=0;
scanf("%d",&n);
fo(i,1,n) scanf("%lld",&a[i]),s+=a[i];
for(ll i=1;i*i<=s;i++)
if(s%i==0)
{
b[++m]=i;
if((s/i)!=i) b[++m]=s/i;
}
fo(k,1,m)
{
ll mod=b[k];
memset(h,0,sizeof(h));
memset(g,0,sizeof(g));
s=0;
ll pos=0;
fo(i,1,n)
{
s=(s+a[i])%mod;
ll p=hash(s);
h[p]=s;
pos=max(pos,++g[p]);
}
ans[pos]=max(ans[pos],mod);
}
for(int i=n-1;i;i--) ans[i]=max(ans[i],ans[i+1]);
fo(i,1,n) printf("%lld\n",ans[i]);
return 0;
}