标签:
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|.
String S consists of at most 250000 lowercase latin letters.
Output |S| lines. On the i-th line output F(i).
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\n",ans[i]); 69 } 70 return 0; 71 }
标签:
原文地址:http://www.cnblogs.com/crackpotisback/p/4730907.html