hysbz3676 回文串 回文自动机
回文自动机模板题
头铁了一下午hdu6599,最后发现自己的板有问题
先放这里一个正确性得到基本确认的板,过两天肝hdu6599
#pragma GCC optimize(2) #include<bits/stdc++.h> #include<iostream> #include<cstring> #include<cassert> #define MAXN 300010 #define LL long long #define BASE 2LL #define MOD 1000000007 using namespace std; char s[MAXN]; int len; LL ans[MAXN]; int qpow(int base,int n){ LL ans=1; while(n){ if(n&1)ans=(ans*base)%MOD; base=(1LL*base*base)%MOD; n>>=1; } return ans; } struct PTnode{ int len,fail,son[26]; LL cnt;//该点对应的回文串出现次数 //建完了树,要再跑一遍,cnt才是正确的 PTnode(){ cnt=len=fail=0; memset(son,0,sizeof son); } }PTdian[MAXN<<1]; int PTlast,PTnum; int PTgetfail(int i,int x){ while(s[i-PTdian[x].len-1]!=s[i]) { x=PTdian[x].fail; } return x; } void PTextend(int i,int x){ int cur=PTgetfail(i,PTlast); if(!PTdian[cur].son[x]){ int now=++PTnum; PTdian[now].len=PTdian[cur].len+2; PTdian[now].fail=PTdian[PTgetfail(i,PTdian[cur].fail)].son[x]; PTdian[cur].son[x]=now; } PTdian[PTdian[cur].son[x]].cnt++; PTlast=PTdian[cur].son[x]; } void PTcount(){ for(int i=PTnum;i>=2;i--){ //逆序累加 PTdian[PTdian[i].fail].cnt+=PTdian[i].cnt; } } //int dfs(int l,int index,int hash1,int hash2){ // if(index>1 && hash1==hash2){ // ans[PTdian[index].len]+=PTdian[index].cnt; // } // for(int i=0;i<26;i++){ // if(PTdian[index].son[i]!=0){ // LL tmp1=(hash1+i*qpow(BASE,l)%MOD)%MOD; // LL tmp2=(BASE*hash2%MOD+i)%MOD; // dfs(l+1,PTdian[index].son[i],tmp1,tmp2); // } // } //} //char a[MAXN]; //int dfs1(int depth,int index){ // //检查回文自动机构造正确性 // for(int i=0;i<depth;i++)printf("%c",a[i]); // printf(" len:%d siz:%d\n",PTdian[index].len,PTdian[index].cnt); // for(int i=0;i<26;i++){ // if(PTdian[index].son[i]!=0){ // a[depth]=i+'a'; // dfs1(depth+1,PTdian[index].son[i]); // } // } //} int main(){ // freopen("1.txt","r",stdin); // freopen("2.txt","w",stdout); while(1){ int rep=scanf("%s",s); if(rep==EOF)break; len=strlen(s); memset(ans,0,sizeof ans);memset(PTdian,0,sizeof PTdian); PTlast=PTnum=1; PTdian[1].len=-1; PTdian[0].fail=PTdian[1].fail=1; for(int i=0;i<len;i++){ PTextend(i,s[i]-'a'); } PTcount(); LL maxx=0; for(int i=2;i<=PTnum;i++){ maxx=max(maxx,1LL*PTdian[i].cnt*PTdian[i].len); } printf("%lld\n",maxx); // dfs(0,0,0,0); // dfs(0,1,0,0); // dfs1(0,0); // dfs1(0,1); // for(int i=1;i<=len;i++)printf("%lld%c",ans[i],(i!=len)?' ':'\n'); } }