POJ-1509 Glass Beads

题意:求一个字符串的最小表示的开始下标。

分析:其实有一个O(N)的算法专门来解决这个问题,并且实现非常简单,不过后缀自动机同样能够解决这个问题。首先把这个串重复两次,然后从前往后一一将字符加入到后缀自动机中,最后从根开始向下遍历串的长度层即可。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 using namespace std;
 7 const int MAXN=10000+10;
 8 char str[MAXN];
 9 struct SAM{
10     struct State{
11         int ch[26];
12         int link,len;
13         void init(){
14             link=-1;
15             len=0;
16             memset(ch,0xff,sizeof(ch));
17         }
18     }st[MAXN<<1];
19     int size,last;
20     void init(){
21         size=last=0;
22         st[size++].init();
23     }
24     int newst(){
25         st[size].init();
26         return size++;
27     }
28     void add(int c){
29         int end=newst();
30         int p=last;
31         st[end].len=st[last].len+1;
32         for(;p!=-1 && st[p].ch[c] == -1;p=st[p].link)
33             st[p].ch[c]=end;
34         if(p == -1) st[end].link=0;
35         else {
36             int nxt=st[p].ch[c];
37             if(st[p].len+1 == st[nxt].len) st[end].link=nxt;
38             else {
39                 int clone=newst();
40                 st[clone]=st[nxt];
41                 st[clone].len=st[p].len+1;
42                 st[end].link=st[nxt].link=clone;
43                 for(;p!=-1 && st[p].ch[c]==nxt;p=st[p].link)
44                     st[p].ch[c]=clone;
45             }
46         }
47         last=end;
48     }
49 }sam;
50 
51 int main(){
52     int T;
53     scanf("%d",&T);
54     while(T--){
55         sam.init();
56         scanf("%s",str);
57         int len=strlen(str);
58         for(int i=0;i<len*2;i++){
59             sam.add(str[i%len]-'a');
60         }
61         int p=0;
62         for(int i=0;i<len;i++){
63             for(int j=0;j<26;j++){
64                 if(sam.st[p].ch[j] != -1){
65                     p=sam.st[p].ch[j];
66                     break;
67                 }
68             }
69         }
70         printf("%d
",sam.st[p].len-len+1);
71     }
72     return(0);
73 }
原文地址:https://www.cnblogs.com/KCkowk/p/6510254.html