len[u]表示结点u所表示的回文串长度,cnt[u]表示结点u所表示的回文串出现次数,num[u]表示结点u的后缀回文串个数(包括自己)。
由于一个字符串本质不同的回文串最多不超过n个,所以空间开n+2即可,算上每个结点的26个Next指针,空间复杂度o(26*n)。时间复杂度o(n)。
struct PalinTree { int ch[maxn][26],f[maxn]; int cnt[maxn],num[maxn],len[maxn]; int s[maxn]; int last,n,tot; int newnode(int l) { MS0(ch[tot]); cnt[tot]=0; num[tot]=0; len[tot]=l; return tot++; } void init() { tot=0; newnode(0); newnode(-1); last=0;n=0; s[n]=-1;f[0]=1; } int get_fail(int x) { while(s[n-len[x]-1]!=s[n]) x=f[x]; return x; } void add(int c) { c-='a'; s[++n]=c; last=get_fail(last); if(!ch[last][c]){ int cur=newnode(len[last]+2); f[cur]=ch[get_fail(f[last])][c]; ch[last][c]=cur; num[cur]=num[f[cur]]+1; } last=ch[last][c]; cnt[last]++; } void count() { for(int i=tot-1;i>=0;i--) cnt[f[i]]+=cnt[i]; } };PalinTree pt;