[poj1509]Glass Beads
最小表示法or后缀自动机。。。
(一个都不会啊,字符串只会hash的说)
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <string> 7 #include <vector> 8 #include <cmath> 9 #include <queue> 10 #include <complex> 11 #include <set> 12 using namespace std; 13 14 const int N=50000; 15 char s[N]; 16 17 18 struct SAM{ 19 int ch[N][30],pre[N],len[N],tot,root,last; 20 int nd(int v){len[++tot]=v;return tot;} 21 void add(int v){ 22 int p=last,np=nd(len[p]+1); 23 while(p&&!ch[p][v])ch[p][v]=np,p=pre[p]; 24 if(!p)pre[np]=root; 25 else{ 26 int q=ch[p][v]; 27 if(len[p]+1==len[q])pre[np]=q; 28 else{ 29 int nq=nd(len[p]+1); 30 memcpy(ch[nq],ch[q],sizeof ch[q]); 31 pre[nq]=pre[q]; 32 pre[q]=pre[np]=nq; 33 while(p&&ch[p][v]==q)ch[p][v]=nq,p=pre[p]; 34 } 35 } 36 last=np; 37 } 38 void init(){ 39 tot=0; 40 last=root=++tot; 41 memset(ch,0,sizeof(ch)); 42 memset(pre,0,sizeof(pre)); 43 memset(len,0,sizeof(len)); 44 } 45 }sam; 46 47 48 int main(){ 49 int N; 50 scanf("%d",&N); 51 while(N--){ 52 sam.init(); 53 scanf("%s",s); 54 int len=strlen(s); 55 for(int i=0;i<len*2;i++)sam.add(s[i%len]-'a'); 56 int p=sam.root; 57 for(int i=0;i<len;i++)for(int j=0;j<26;j++)if(sam.ch[p][j]){p=sam.ch[p][j];break;} 58 printf("%d\n",sam.len[p]-len+1); 59 } 60 }