【JZOJ 4922】 环

来源:互联网 发布:上海程序员工资多少 编辑:程序博客网 时间:2024/05/17 08:31

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;}
0 0
原创粉丝点击