后缀自动机三·重复旋律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\n", ans[i]); 82 } 83 }