题目分析:
模板练手。看最长能走多远。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 using namespace std; 7 8 const int maxn = 50500; 9 10 int son[maxn][30],fa[maxn],maxlen[maxn],root,num; 11 12 string str; 13 14 int addnew(int dt){maxlen[++num] = dt;return num;} 15 int ins(char x,int p){ 16 int np = addnew(maxlen[p]+1); 17 while(p && !son[p][x-'a']) son[p][x-'a'] = np,p = fa[p]; 18 if(!p){fa[np] = root; return np;} 19 else{ 20 int q = son[p][x-'a']; 21 if(maxlen[q]==maxlen[p]+1){fa[np]=q;return np;} 22 else{ 23 int nq = addnew(maxlen[p]+1); 24 for(int i=0;i<26;i++) son[nq][i] = son[q][i]; 25 fa[nq] = fa[q]; fa[q] = fa[np] = nq; 26 while(p && son[p][x-'a'] == q) son[p][x-'a'] = nq,p = fa[p]; 27 return np; 28 } 29 } 30 } 31 32 void dfs(int now,int cnt){ 33 int flag = 0; 34 for(int i=0;i<26;i++){ 35 if(!son[now][i]) continue; 36 dfs(son[now][i],cnt+1); flag = 1; 37 break; 38 } 39 if(!flag){cout<<str.length()-cnt+1<<endl;} 40 } 41 42 void init(){ 43 for(int i=1;i<=num;i++) memset(son[i],0,sizeof(son[i])); 44 for(int i=1;i<=num;i++) fa[i] = maxlen[i] = 0; 45 root = 0; num = 0; 46 } 47 48 void work(){ 49 int lst = addnew(0);root = lst; 50 for(int i=0;i<str.length();i++) 51 lst = ins(str[i],lst); 52 dfs(root,0); 53 } 54 55 int main(){ 56 ios::sync_with_stdio(false); 57 cin.tie(0); 58 int Tmp; cin >> Tmp; 59 while(Tmp--){ 60 init(); 61 cin >> str; 62 str+=str; 63 work(); 64 } 65 return 0; 66 }