标签:
这里要在后缀自动机的节点中维护一个从到达当前位置出现的字符串总个数
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 5 using namespace std; 6 #define N 200010 7 #define M 26 8 9 struct SamNode{ 10 SamNode *son[26] , *f; 11 int l , sc; 12 void init(){ 13 f = NULL; 14 for(int i=0 ; i<26 ; i++) son[i] = NULL; 15 l = sc = 0; 16 } 17 }*root , *last , sam[N]; 18 19 int cnt , n , m , k , ret; 20 char s[N]; 21 22 void init(){ 23 sam[0].init(); 24 root = last = &sam[cnt=0]; 25 ret = 0; 26 } 27 28 void add(int x) 29 { 30 SamNode *p = &sam[++cnt] , *jp=last; 31 p->init(); 32 p->l = jp->l+1; 33 p->sc=1; 34 last = p; 35 for( ; jp&&!jp->son[x] ; jp=jp->f) jp->son[x]=p; 36 if(!jp) p->f = root; 37 else{ 38 if(jp->l+1 == jp->son[x]->l) p->f = jp->son[x]; 39 else{ 40 SamNode *r = &sam[++cnt] , *q = jp->son[x]; 41 r->init(); 42 *r = *q; 43 r->l = jp->l+1; 44 q->f = p->f = r; 45 for( ; jp && jp->son[x]==q ; jp=jp->f) jp->son[x]=r; 46 } 47 } 48 p = last; 49 while(p->f){ 50 p = p->f; 51 p->sc++; 52 } 53 } 54 char str[55]; 55 int solve() 56 { 57 SamNode *cur = root; 58 int len = strlen(str); 59 for(int i=0 ; i<len ; i++){ 60 int v = str[i]-‘a‘; 61 if(cur->son[v]){ 62 cur = cur->son[v]; 63 } 64 else{ 65 return 0; 66 } 67 } 68 return cur->sc; 69 } 70 71 72 int main() 73 { 74 // freopen("data_in.txt" , "r" , stdin); 75 int n , m , op; 76 while(~scanf("%d%d" , &n , &m)) 77 { 78 scanf("%s" , s); 79 80 init(); 81 for(int i=0 ; i<n ; i++) add(s[i]-‘a‘); 82 while(m--){ 83 // cout<<m<<endl; 84 scanf("%d" , &op); 85 if(op==2){ 86 // cout<<"in"<<endl; 87 scanf("%s" , str); 88 printf("%d\n" , solve()); 89 90 } 91 else{ 92 scanf("%s" , str); 93 add(str[0]-‘a‘); 94 } 95 } 96 } 97 return 0; 98 }
标签:
原文地址:http://www.cnblogs.com/CSU3901130321/p/4734537.html