K-string
Time Limit: 2000ms
Memory Limit: 131072KB
This problem will be judged on HDU. Original ID: 464164-bit integer IO format: %I64d Java class name: Main
Given a string S. K-string is the sub-string of S and it appear in the S at least K times.It means there are at least K different pairs (i,j) so that Si,Si+1... Sj equal to this K-string. Given m operator or query:1.add a letter to the end of S; 2.query how many different K-string currently.For each query ,count the number of different K-string currently.
Input
The input consists of multiple test cases.
Each test case begins with a line containing three integers n, m and K(1<=n,K<=50000,1<=m<=200000), denoting the length of string S, the number of operator or question and the least number of occurrences of K-string in the S.
The second line consists string S,which only contains lowercase letters.
The next m lines describe the operator or query.The description of the operator looks as two space-separated integers t c (t = 1; c is lowercase letter).The description of the query looks as one integer t (t = 2).
Each test case begins with a line containing three integers n, m and K(1<=n,K<=50000,1<=m<=200000), denoting the length of string S, the number of operator or question and the least number of occurrences of K-string in the S.
The second line consists string S,which only contains lowercase letters.
The next m lines describe the operator or query.The description of the operator looks as two space-separated integers t c (t = 1; c is lowercase letter).The description of the query looks as one integer t (t = 2).
Output
For each query print an integer — the number of different K-string currently.
Sample Input
3 5 2 abc 2 1 a 2 1 a 2
Sample Output
0 1 1
Source
解题:后缀自动机
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 600010; 5 int n,m,k; 6 LL ret; 7 struct node{ 8 int son[26],f,len,num; 9 void init(){ 10 f = -1; 11 num = len = 0; 12 memset(son,-1,sizeof son); 13 } 14 }; 15 struct SAM{ 16 node e[maxn]; 17 int tot,last; 18 int newnode(int len = 0){ 19 e[tot].init(); 20 e[tot].len = len; 21 return tot++; 22 } 23 void init(){ 24 tot = last = 0; 25 newnode(); 26 } 27 void add(int c){ 28 int p = last,np = newnode(e[p].len + 1); 29 while(p != -1 && e[p].son[c] == -1){ 30 e[p].son[c] = np; 31 p = e[p].f; 32 } 33 if(p == -1) e[np].f = 0; 34 else{ 35 int q = e[p].son[c]; 36 if(e[p].len + 1 == e[q].len) e[np].f = q; 37 else{ 38 int nq = newnode(); 39 e[nq] = e[q]; 40 e[nq].len = e[p].len + 1; 41 e[q].f = e[np].f = nq; 42 while(p != -1 && e[p].son[c] == q){ 43 e[p].son[c] = nq; 44 p = e[p].f; 45 } 46 } 47 } 48 for(p = np; p != -1; p = e[p].f){ 49 if(e[p].num == k) break; 50 if(++e[p].num == k){ 51 ret += e[p].len - e[e[p].f].len; 52 break; 53 } 54 } 55 last = np; 56 } 57 }sam; 58 char str[maxn]; 59 int main(){ 60 int op; 61 while(~scanf("%d%d%d",&n,&m,&k)){ 62 scanf("%s",str); 63 sam.init(); 64 ret = 0; 65 for(int i = 0; str[i]; ++i) 66 sam.add(str[i] - 'a'); 67 for(int i = 0; i < m; ++i){ 68 scanf("%d",&op); 69 if(op == 1){ 70 scanf("%s",str); 71 sam.add(str[0] - 'a'); 72 }else printf("%d ",ret); 73 } 74 } 75 return 0; 76 }