后缀自动机三·重复旋律6

后缀自动机三·重复旋律6

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1000010;
 4 char s[maxn];
 5 int maxlen[maxn<<1], minlen[maxn<<1], tr[maxn<<1][26], link[maxn<<1];
 6 int green[maxn<<1], ind[maxn<<1], cnt[maxn<<1];
 7 int ans[maxn];
 8 int sz;
 9 
10 int news(int maxl, int minl, int *trans, int lk){
11     maxlen[sz] = maxl;
12     minlen[sz] = minl;
13     green[sz] = 0;
14     cnt[sz] = 0;
15     ind[sz] = 0;
16     for(int i = 0; i < 26; i++){
17         if(trans == NULL) tr[sz][i] = -1;
18         else tr[sz][i] = trans[i];
19     }
20     link[sz] = lk;
21     return sz++;
22 }
23 int add(char ch, int u){
24     int c = ch - 'a';
25     int z = news(maxlen[u] + 1, -1, NULL, -1);
26     green[z] = 1;
27     int v = u;
28     while(~v && tr[v][c] == -1){
29         tr[v][c] = z;
30         v = link[v];
31     }
32     if(v == -1){
33         minlen[z] = 1;
34         link[z] = 0;
35         ind[0]++;
36         return z;
37     }
38     int x = tr[v][c];
39     if(maxlen[v] + 1 == maxlen[x]){
40         minlen[z] = maxlen[x] + 1;
41         link[z] = x;
42         ind[x]++;
43         return z;
44     }
45     int y = news(maxlen[v] + 1, -1, tr[x], link[x]);
46     minlen[x] = maxlen[y] + 1;
47     link[x] = y;
48     minlen[z] = maxlen[y] + 1;
49     link[z] = y;
50     ind[y] += 2;
51     int w = v;
52     while(~w && tr[w][c] == x){
53         tr[w][c] = y;
54         w = link[w];
55     }
56     minlen[y] = maxlen[link[y]] + 1;
57     return z;
58 }
59 void top(){
60     queue<int> q;
61     for(int i = 0; i < sz; i++) if(!ind[i]) q.push(i);
62     while(!q.empty()){
63         int u = q.front();
64         q.pop();
65         if(green[u]) cnt[u]++;
66         cnt[link[u]] += cnt[u];
67         if(!(--ind[link[u]])) q.push(link[u]);
68     }
69 }
70 int main(){
71     while(scanf("%s", s) != EOF){
72         int len = strlen(s);
73         sz = 0;
74         int pre = news(0, 0, NULL, -1);
75         for(int i = 0; i < len; i++){
76             pre = add(s[i], pre);
77         }
78         top();
79         for(int i = 0; i < sz; i++) ans[maxlen[i]] = max(ans[maxlen[i]], cnt[i]);
80         for(int i = len - 1; i > 0; i--) ans[i] = max(ans[i], ans[i + 1]);
81         for(int i = 1; i <= len; i++) printf("%d
", ans[i]);
82     }
83 }
View Code
原文地址:https://www.cnblogs.com/yijiull/p/8506372.html