BZOJ P2081[Poi2010]Beads

来源:互联网 发布:数码大师软件多大 编辑:程序博客网 时间:2024/06/05 11:01

hash

直接求一遍前缀积后缀积

然后枚举长度和左端点做就可以了

下面是代码

#include<iostream>#include<cstring>#include<algorithm>#include<map>#define N 200010const int base=2333;const int mod=987654321;using namespace std;int a[N],h[N],g[N],cf[N];int ans[N];map<int,bool>p;int geth(int x,int y){    x--;    return ((h[y]-(long long)h[x]*cf[y-x]%mod)+mod)%mod;  }int getg(int x,int y){    y++;    return ((g[x]-(long long)g[y]*cf[y-x]%mod)+mod)%mod;}int main(){    int n;    cin>>n;    int i,j,x,y;    cf[0]=1;    for(i=1;i<=n;i++){    cf[i]=(long long)cf[i-1]*base%mod;}    for(i=1;i<=n;i++){        cin>>a[i];        h[i]=((long long)h[i-1]*base+a[i])%mod;    }    for(i=n;i>=1;i--){    g[i]=((long long)g[i+1]*base+a[i])%mod;}    int maxn=0;int tot=0;    for(i=1;maxn*i<=n;i++){        p.clear();        int now=0;        for(j=1;j+i-1<=n;j+=i){            int h1=geth(j,j+i-1);int h2=getg(j,j+i-1);            if(!p[h1]||!p[h2]){                now++;                p[h1]=p[h2]=true;            }        }        if(now>maxn){            maxn=now;            tot=1;            ans[1]=i;        }else if(now==maxn){            tot++;            ans[tot]=i;        }    }    cout<<maxn<<" "<<tot<<endl<<ans[1];    for(i=2;i<=tot;i++){    cout<<" "<<ans[i];}    return 0;}/*in:211 1 1 2 2 2 3 3 3 1 2 3 3 1 2 2 1 3 3 2 1out:6 12*/


1 0
原创粉丝点击