回文自动机
今天上午LargeDumpling给我来了一发字符串专题Orz
于是下午来了一发回文自动机
板:
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 const int xxxx=600010;//length 34 namespace pam 35 { 36 int ch[xxxx][26];//son 37 int pre[xxxx];//fail 38 int sum[xxxx];//times 39 int len[xxxx];//Max_length 40 int ss[xxxx];//string 41 int num[xxxx];//numbers 42 int last,n,ed=-1; 43 int newnode(int x)//you_know 44 { 45 len[++ed]=x; 46 return ed; 47 } 48 void init()//pretreatment 49 { 50 newnode(0),newnode(-1); 51 last=n=0;ss[n]=-1,pre[0]=pre[1]=1; 52 } 53 int getfail(int x)//you_know 54 { 55 while(ss[n-len[x]-1]!=ss[n])x=pre[x]; 56 return x; 57 } 58 void add(int c)//add_a_char 59 { 60 c-='a'; 61 ss[++n]=c; 62 int temp=getfail(last); 63 if(!ch[temp][c]) 64 { 65 int now=newnode(len[temp]+2); 66 int k=getfail(pre[temp]); 67 pre[now]=ch[k][c]; 68 ch[temp][c]=now; 69 num[now]=num[pre[now]]+1; 70 } 71 last=ch[temp][c]; 72 sum[last]++; 73 } 74 void add(char *s)//add_a_string 75 { 76 int limit=strlen(s); 77 re(i,0,limit-1)add(s[i]); 78 } 79 void count()//clac_times 80 { 81 rre(i,ed,1)sum[pre[i]]+=sum[i]; 82 } 83 } 84 char s[xxxx]; 85 int main() 86 { 87 strin(s); 88 pam::init(); 89 pam::add(s); 90 pam::count(); 91 return 0; 92 }