bzoj2081: [Poi2010]Beads

来源:互联网 发布:山东邮政网络培训学院 编辑:程序博客网 时间:2024/05/27 16:41

传送门
哈希被卡了。孟戴章峥
直接暴力+哈希驶过去,但是模数要取好。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<cstdlib>#define bas 200019#define mo 1000000009#define ll long longusing namespace std;int n,ans,a[bas],sta[bas],top;ll hs1[bas],hs2[bas],power[bas];namespace Hash{    struct node{        int val;        bool flag;        node *nxt;        node(int _,node *__):            val(_),flag(0),nxt(__){}    }*head[bas];    int tim[bas],T;    void pre(){T++;}    bool& hash(int val){        int pos=val%bas;        if (tim[pos]!=T) tim[pos]=T,head[pos]=0x0;        for (node *tmp=head[pos];tmp;tmp=tmp->nxt)            if (tmp->val==val) return tmp->flag;        return (head[pos]=new node(val,head[pos]))->flag;     }}int main(){    using namespace Hash;    scanf("%d",&n);    for (int i=1;i<=n;i++) scanf("%d",&a[i]);    for (int i=1;i<=n;i++) hs1[i]=(hs1[i-1]*bas+a[i])%mo;    for (int i=n;i>=1;i--) hs2[i]=(hs2[i+1]*bas+a[i])%mo;    for (int i=power[0]=1;i<=n;i++) power[i]=power[i-1]*bas%mo;    for (int i=1;i<=n;i++){        int tot=0;        pre();        for (int j=i;j<=n;j+=i){            int l=j-i+1,r=j;            ll tmp1=(hs1[r]-hs1[l-1]*power[r-l+1]%mo+mo)%mo;            ll tmp2=(hs2[l]-hs2[r+1]*power[r-l+1]%mo+mo)%mo;            bool &flag=hash(tmp1*tmp2%mo);            if (!flag) ++tot;            flag=1;         }        if (tot>ans) ans=tot,top=0;        if (tot==ans) sta[++top]=i;    }    printf("%d %d\n",ans,top);    for (int i=1;i<=top;i++){        printf("%d",sta[i]);        if (i!=top) printf(" ");    }}
1 0
原创粉丝点击