回文树详解
无。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 //#include<time.h> 5 //#include<complex> 6 //#include<set> 7 //#include<queue> 8 #include<algorithm> 9 #include<stdlib.h> 10 using namespace std; 11 12 #define LL long long 13 int qread() 14 { 15 char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1); 16 do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f; 17 } 18 19 //Pay attention to '-' , LL and double of qread!!!! 20 21 int n,m; 22 #define maxn 1000011 23 char s[maxn]; 24 struct PT 25 { 26 struct Node{int ch[26],len,pre,cnt;}a[maxn]; 27 int last,size; 28 PT() {size=2; last=2; a[1].len=-1; a[2].len=0; a[2].pre=a[1].pre=1;} 29 void insert(int c,int p) 30 { 31 int y=last,len=0; 32 while (1) 33 { 34 len=a[y].len; 35 if (p-len-1>=0 && s[p-len-1]==s[p]) break; 36 y=a[y].pre; 37 } 38 if (a[y].ch[c]) {last=a[y].ch[c]; a[last].cnt++; return;} 39 int x=last=++size; 40 a[x].len=a[y].len+2; a[y].ch[c]=x; a[x].cnt=1; 41 if (a[x].len==1) {a[x].pre=2; return;} 42 while (1) 43 { 44 y=a[y].pre; 45 len=a[y].len; 46 if (p-1-len>=0 && s[p-len-1]==s[p]) 47 { 48 a[x].pre=a[y].ch[c]; 49 break; 50 } 51 } 52 } 53 void hei() 54 { 55 for (int i=size;i;i--) a[a[i].pre].cnt+=a[i].cnt; 56 } 57 void test() 58 { 59 for (int i=1;i<=size;i++) cout<<a[i].len<<' '<<a[i].pre<<endl; 60 } 61 }pt; 62 63 int main() 64 { 65 scanf("%s",s+1); n=strlen(s+1); 66 for (int i=1;i<=n;i++) pt.insert(s[i]-'a',i); 67 pt.hei(); 68 int ans=0; 69 for (int i=3;i<=pt.size;i++) ans+=pt.a[i].cnt; 70 printf("%d\n",ans); 71 return 0; 72 }