# Substring

## 题解

### 参考代码

#include <bits/stdc++.h>

const int MAXN=2e6+10;
int size[MAXN];

#define lch chd[0]
#define rch chd[1]
#define kch chd[k]
#define xch chd[k^1]

struct Node{
int val;
bool rev;
Node* prt;
Node* pprt;
Node* chd[2];
this->lch=this->rch=NULL;
}
void Flip(){
if(this!=NULL){
this->rev=!this->rev;
std::swap(this->lch,this->rch);
}
}
if(this!=NULL){
this->val+=x;
}
}
void PushDown(){
}
if(this->rev){
this->lch->Flip();
this->rch->Flip();
this->rev=false;
}
}
};
std::vector<Node*> N;
void Rotate(Node* root,int k){
Node* tmp=root->xch;
root->PushDown();
tmp->PushDown();
tmp->prt=root->prt;
if(root->prt==NULL){
tmp->pprt=root->pprt;
root->pprt=NULL;
}
else if(root->prt->lch==root)
root->prt->lch=tmp;
else
root->prt->rch=tmp;
root->xch=tmp->kch;
if(root->xch!=NULL)
root->xch->prt=root;
tmp->kch=root;
root->prt=tmp;
}
void Splay(Node* root){
while(root->prt!=NULL){
int k=root->prt->lch==root;
if(root->prt->prt==NULL)
Rotate(root->prt,k);
else{
int d=root->prt->prt->lch==root->prt;
Rotate(k==d?root->prt->prt:root->prt,k);
Rotate(root->prt,d);
}
}
}
void Expose(Node* root){
Splay(root);
root->PushDown();
if(root->rch!=NULL){
root->rch->prt=NULL;
root->rch->pprt=root;
root->rch=NULL;
}
}
bool Splice(Node* root){
Splay(root);
if(root->pprt==NULL)
return false;
Expose(root->pprt);
root->pprt->rch=root;
root->prt=root->pprt;
root->pprt=NULL;
return true;
}
void Access(Node* root){
Expose(root);
while(Splice(root));
assert(root->pprt==0&&root->prt==0);
}
void Evert(Node* root){
Access(root);
root->Flip();
}
void Add(int y,int d){
Evert(N[1]);
Access(N[y]);
}
void Link(int prt,int son){
Evert(N[son]);
N[son]->pprt=N[prt];
Evert(N[1]);
Access(N[prt]);
}
void Cut(int prt,int son){
Evert(N[1]);
Access(N[son]);
Access(N[prt]);
Access(N[son]);
N[son]->PushDown();
N[son]->lch->prt=NULL;
N[son]->lch=NULL;
}
int Query(int x){
Access(N[x]);
return N[x]->val;
}
void MakeTree(int x){
N.push_back(new Node(x));
}

int q;
int cnt=1;
int root=1;
int last=1;
char s[MAXN];
int prt[MAXN];
int len[MAXN];
std::map<char,int> chd[MAXN];

int Query(char*);
void Extend(char);
void Extend(char*);
void Decode(char*,int);

int main(){
scanf("%d",&q);
scanf("%s",s);
T->MakeTree(0);
Extend(s);
while(q--){
scanf("%s",s);
if(*s=='A'){
scanf("%s",s);
Extend(s);
}
else{
scanf("%s",s);
int x=Query(s);
printf("%d\n",x);
}
}
return 0;
}

int Query(char* s){
int cur=root;
while(*s!='\0'){
if(!chd[cur].count(*s))
return 0;
else
cur=chd[cur][*s];
++s;
}
return T->Query(cur);
}

void Decode(char* s,int mask){
int len=strlen(s);
for(int i=0;i<len;i++){
char t=s[i];
}
}

void Extend(char* s){
while(*s!='\0')
Extend(*(s++));
}

void Extend(char x){
int p=last;
int np=++cnt;
T->MakeTree(1);
size[last=np]=1;
len[np]=len[p]+1;
while(p&&!chd[p].count(x))
chd[p][x]=np,p=prt[p];
if(p==0)
prt[np]=root;
else{
int q=chd[p][x];
if(len[q]==len[p]+1)
prt[np]=q;
else{
int nq=++cnt;
T->MakeTree(0);
chd[nq]=chd[q];
prt[nq]=prt[q];
T->Cut(prt[q],q);