# [BZOJ2555]SubString(SAM+LCT)

## 2555: SubString

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 4077  Solved: 1236
[Submit][Status][Discuss]

## Description

(1):在当前字符串的后面插入一个字符串
(2):询问字符串s在当前字符串中出现了几次？(作为连续子串)

## Input

Type是QUERY的话表示询问某字符串在当前字符串中出现了几次。

2
A
QUERY B

0

## Source

[Submit][Status][Discuss]

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 #define ls ch[x][0]
5 #define rs ch[x][1]
6 #define rep(i,l,r) for (int i=l; i<=r; i++)
7 using namespace std;
8
9 const int N=1200010;
11 char op[10],S[3000100];
12
13 bool isroot(int x){ return (!f[x]) || (ch[f[x]][0]!=x && ch[f[x]][1]!=x); }
14 void put(int x,int k){ w[x]+=k; tag[x]+=k; }
15 void push(int x){ if (tag[x]) put(ls,tag[x]),put(rs,tag[x]),tag[x]=0; }
16 void pd(int x){ if (!isroot(x)) pd(f[x]); push(x); }
17
18 void rot(int x){
19     int y=f[x],z=f[y],w=ch[y][1]==x;
20     if (!isroot(y)) ch[z][ch[z][1]==y]=x;
21     f[x]=z; f[y]=x; f[ch[x][w^1]]=y;
22     ch[y][w]=ch[x][w^1]; ch[x][w^1]=y;
23 }
24
25 void splay(int x){
26     pd(x);
27     while (!isroot(x)){
28         int y=f[x],z=f[y];
29         if (!isroot(y)) rot((ch[z][0]==y)^(ch[y][0]==x) ? x : y);
30         rot(x);
31     }
32 }
33
34 void access(int x){ for (int y=0; x; y=x,x=f[x]) splay(x),ch[x][1]=y; }
35 void link(int x,int y){ f[x]=y; access(y); splay(y); put(y,w[x]); }
36 void cut(int x){ access(x); splay(x); put(ls,-w[x]); f[ls]=0; ch[x][0]=0; }
37 int que(int x){ splay(x); return w[x]; }
38
39 void ext(int c){
40     int p=lst,np=lst=++cnt; mx[np]=mx[p]+1; w[np]=1;
41     while (p && !son[p][c]) son[p][c]=np,p=fa[p];
43     else{
44         int q=son[p][c];
46         else{
47             int nq=++cnt; mx[nq]=mx[p]+1;
48             while (p && son[p][c]==q) son[p][c]=nq,p=fa[p];
49             memcpy(son[nq],son[q],sizeof(son[q]));
52         }
53     }
54 }
55
57     scanf("%s",S); len=strlen(S);
59 }
60
61 int main(){
62     freopen("bzoj2555.in","r",stdin);
63     freopen("bzoj2555.out","w",stdout);
64     scanf("%d",&Q); scanf("%s",S); len=strlen(S);
65     for (int i=0; i<len; i++) ext(S[i]-'A'+1);
66     rep(i,1,Q){
67         scanf("%s",op);
68         if (op[0]=='A'){ get(mask); for (int j=0; j<len; j++) ext(S[j]-'A'+1); }
69         else{
71             for (int j=0; j<len; j++){
72                 if (!son[x][S[j]-'A'+1]){ flag=1; puts("0"); break; }
73                 x=son[x][S[j]-'A'+1];
74             }
75             if (flag) continue;
80 }