SPOJ NSUBSTR

NSUBSTR - Substrings

no tags 

You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as the maximal number of times that some string with length x appears in S. For example for string 'ababa' F(3) will be 2 because there is a string 'aba' that occurs twice. Your task is to output F(i) for every i so that 1<=i<=|S|.

Input

String S consists of at most 250000 lowercase latin letters.

Output

Output |S| lines. On the i-th line output F(i).

Example

 
Input:
ababa

Output:
3
2
2
1
1

解题:SAM求出现次数最多的且长度为i的串的次数

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 351000;
 4 struct SAM {
 5     struct node {
 6         int son[26],f,len;
 7         void init() {
 8             f = -1;
 9             len = 0;
10             memset(son,-1,sizeof son);
11         }
12     } s[maxn<<1];
13     int tot,last;
14     void init() {
15         tot = last = 0;
16         s[tot++].init();
17     }
18     int newnode() {
19         s[tot].init();
20         return tot++;
21     }
22     void extend(int c){
23         int np = newnode(),p = last;
24         s[np].len = s[p].len + 1;
25         while(p != -1 && s[p].son[c] == -1){
26             s[p].son[c] = np;
27             p = s[p].f;
28         }
29         if(p == -1) s[np].f = 0;
30         else{
31             int q = s[p].son[c];
32             if(s[p].len + 1 == s[q].len) s[np].f = q;
33             else{
34                 int nq = newnode();
35                 s[nq] = s[q];
36                 s[nq].len = s[p].len + 1;
37                 s[q].f = s[np].f = nq;
38                 while(p != -1 && s[p].son[c] == q){
39                     s[p].son[c] = nq;
40                     p = s[p].f;
41                 }
42             }
43         }
44         last = np;
45     }
46 } sam;
47 char str[maxn];
48 int c[maxn<<1],ans[maxn],rk[maxn<<1],w[maxn];
49 int main() {
50     while(~scanf("%s",str)) {
51         sam.init();
52         int len = strlen(str);
53         for(int i = 0; i < len; ++i)
54             sam.extend(str[i] - 'a');
55         memset(ans,0,sizeof ans);
56         memset(c,0,sizeof c);
57         memset(w,0,sizeof w);
58         for(int i = 1; i < sam.tot; ++i) ++w[sam.s[i].len];
59         for(int i = 1; i <= len; ++i) w[i] += w[i-1];
60         for(int i = sam.tot-1; i > 0; --i) rk[w[sam.s[i].len]--] = i;
61         for(int i = 0, p = 0; i < len; ++i)
62             ++c[p = sam.s[p].son[str[i]-'a']];
63         for(int i = sam.tot-1; i > 0; --i) {
64             ans[sam.s[rk[i]].len] = max(ans[sam.s[rk[i]].len],c[rk[i]]);
65             if(sam.s[rk[i]].f > 0) c[sam.s[rk[i]].f] += c[rk[i]];
66         }
67         for(int i = 1; i <= len; ++i)
68             printf("%d
",ans[i]);
69     }
70     return 0;
71 }
View Code


原文地址:https://www.cnblogs.com/crackpotisback/p/4730907.html