# bzoj2555: SubString

  1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cmath>
5 #include <algorithm>
6 #define maxn 1200005
7 #define maxl 3000005
8 using namespace std;
9
10 int q,n,tot,root,last,mark,m,ri[maxn],lazy[maxn];
11 char st[maxl];
12 void watch(){
13     int temp=mark;
14     for (int i=1;i<=m;i++){
15         temp=(temp*131+i-1)%m+1;
16         char t=st[i]; st[i]=st[temp],st[temp]=t,temp--;
17     }
18 }
19 struct Date{
20     int fa[maxn],son[maxn][2];
21     int which(int x){
22         return son[fa[x]][1]==x;
23     }
24     bool isroot(int x){
25         return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;
26     }
27     void change(int x,int y){
28         ri[x]+=y,lazy[x]+=y;
29     }
30     void pushdown(int x){
31         if (lazy[x]==0) return;
32         if (son[x][0]) change(son[x][0],lazy[x]);
33         if (son[x][1]) change(son[x][1],lazy[x]);
34         lazy[x]=0;
35     }
36     void relax(int x){
37         if (!isroot(x)) relax(fa[x]);
38         pushdown(x);
39     }
40     void rotata(int x){
41         int y=fa[x],dd=which(y),d=which(x);
42         if (!isroot(y)) son[fa[y]][dd]=x; fa[x]=fa[y];
43         fa[son[x][d^1]]=y,son[y][d]=son[x][d^1];
44         fa[y]=x,son[x][d^1]=y;
45     }
46     void splay(int x){
47         relax(x);
48         while (!isroot(x)){
49             if (isroot(fa[x])) rotata(x);
50             else if (which(x)==which(fa[x])) rotata(fa[x]),rotata(x);
51             else rotata(x),rotata(x);
52         }
53     }
54     void access(int x){
55         for (int p=0;x;x=fa[x]){
56             splay(x);
57             son[x][1]=p;
58             p=x;
59         }
60     }
62         fa[x]=y,access(y),splay(y),change(y,ri[x]);
63     }
64     void cut(int x){
65         access(x),splay(x),change(son[x][0],-ri[x]),fa[son[x][0]]=0,son[x][0]=0;
66     }
67 }lct;
68 struct Tsegment{
69     int fa[maxn],son[maxn][26],dist[maxn];
70     void prepare(){tot=root=last=1;memset(lazy,0,sizeof(lazy)); memset(ri,0,sizeof(ri));}
71     int newnode(int x){
73     }
75         int p=last,np=newnode(dist[last]+1); last=np,ri[np]=1;
76         for (;p&&!son[p][x];p=fa[p]) son[p][x]=np;
78         else{
79             int q=son[p][x];
81             else{
82                 int nq=newnode(dist[p]+1); ri[nq]=0;
83                 memcpy(son[nq],son[q],sizeof(son[q]));
86                 for (;p&&son[p][x]==q;p=fa[p]) son[p][x]=nq;
87             }
88         }
89     }
90     void build(){
92     }
93     void query(){
94         int x,y;
95         bool can=1;
96         x=root;
97         for (int i=1;i<=m;i++){
98             y=st[i]-'A';
99             if (!son[x][y]){
100                 can=0;
101                 break;
102             }else{
103                 x=son[x][y];
104             }
105         }
106         if (can==0||x==root) puts("0");
107         else{
108             lct.splay(x);
109             printf("%d\n",ri[x]),mark^=ri[x];
110         }
111     }
112 }SAM;
113
114 int main(){
115     scanf("%d",&q),mark=0;
116     scanf("%s",st+1),m=strlen(st+1);
117     SAM.prepare();
118     SAM.build();
119     while (q--){
120         scanf("%s",st+1);
121         if (st[1]=='A') scanf("%s",st+1),m=strlen(st+1),watch(),SAM.build();
122         else scanf("%s",st+1),m=strlen(st+1),watch(),SAM.query();
123     }
124     return 0;
125 }
View Code

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

posted @ 2016-06-01 19:54  oyzx~  阅读(123)  评论(0编辑  收藏  举报