bzoj2555 SubString

sam上维护lct,一直想做(?)一道这样的题终于在sxy的带领下做了一道最简单的模板题。

因为强制在线,又要增量的构建后缀自动机,就用lct动态维护parent树。每增加一个字符,就把它从parent树上到跟的这一段路径上的权值+1,这个可以用个懒标记维护。

然后就是后缀自动机上操作跟平时一样,只是连上父亲和新加节点换父亲等操作的时候在lct上做一遍相同操作即可。

需要注意的是加密的时候mask要传值进去,函数中mask会变但实际的mask是不变的,成功被坑 ( :。

  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<cstdio>
  7 #include<vector>
  8 #include<queue>
  9 #include<cmath>
 10 #include<ctime>
 11 const int N=3000005;
 12 typedef long long LL;
 13 using namespace std;
 14 int mask,Q,len;
 15 string chars;
 16 char s[N],op[N];
 17 
 18 template<typename T> void read(T &x) {
 19     T f=1; x=0; char ch=getchar();
 20     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
 21     if(ch=='-') f=-1,ch=getchar();
 22     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
 23 }
 24 
 25 void gets(int mask) {
 26     scanf("%s",s);
 27     chars=s;
 28     for (int j=0;j<chars.length();j++)  {
 29         mask=(mask*131+j)%chars.length();
 30         char t=chars[j];
 31         chars[j]=chars[mask];
 32         chars[mask]=t;
 33     }
 34 }
 35 
 36 #define lc ch[x][0]
 37 #define rc ch[x][1]
 38 struct lct{
 39     int ch[N][2],p[N],sz[N],lz[N];
 40     
 41     void down(int x) {
 42         if(!lz[x]) return;
 43         if(lc) { sz[lc]+=lz[x]; lz[lc]+=lz[x];}
 44         if(rc) { sz[rc]+=lz[x]; lz[rc]+=lz[x];}
 45         lz[x]=0;
 46     }
 47     
 48     int isroot(int x) { return (ch[p[x]][0]!=x&&ch[p[x]][1]!=x);}
 49     
 50     void rotate(int x) {
 51         int y=p[x],z=p[y],l=(x==ch[y][1]),r=l^1;
 52         if(!isroot(y)) ch[z][y==ch[z][1]]=x; p[x]=z;
 53         ch[y][l]=ch[x][r]; p[ch[x][r]]=y;
 54         ch[x][r]=y; p[y]=x; 
 55     }
 56     
 57     void splay(int x) {
 58         static int g[N],top=0,tp;
 59         for(tp=x;!isroot(tp);tp=p[tp]) g[++top]=tp;
 60         g[++top]=tp;
 61         while(top) down(g[top--]);
 62         for(;!isroot(x);rotate(x)) {
 63             int y=p[x],z=p[y];
 64             if(!isroot(y)) 
 65                 ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y);
 66         }
 67     }
 68     
 69     void access(int x) {
 70         for(int t=0;x;x=p[t=x]) {
 71             splay(x);
 72             rc=t;
 73         }
 74     }
 75     
 76     void add(int x,int v) {
 77         if(!x) return;
 78         sz[x]+=v; lz[x]+=v;
 79     }
 80     
 81     void lik(int x,int y) {
 82         p[x]=y; access(y); splay(y); add(y,sz[x]); 
 83     }
 84     
 85     void cut(int x) {
 86         access(x); splay(x); add(lc,-sz[x]);
 87         p[lc]=0; lc=0;
 88     }
 89     
 90 }t;
 91 
 92 struct SAM {
 93     int last,rt,tot,ch[N][26],fa[N],l[N],p,np,q,nq;
 94     
 95     void init() {
 96         last=rt=tot=1;
 97     } 
 98     
 99     void insert(int c) {
100         p=last; np=++tot; t.sz[np]=1; last=np; 
101         l[np]=l[p]+1;
102         for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
103         if(!p) {
104             fa[np]=rt;
105             t.lik(np,rt);
106         }
107         else {
108             int q=ch[p][c];
109             if(l[q]==l[p]+1) {
110                 fa[np]=q;
111                 t.lik(np,q);
112             }
113             else {
114                 nq=++tot; l[nq]=l[p]+1;
115                 memcpy(ch[nq],ch[q],sizeof(ch[q]));
116                 fa[nq]=fa[q]; t.lik(nq,fa[q]);
117                 fa[q]=fa[np]=nq;
118                 t.cut(q); t.lik(q,nq); t.lik(np,nq);   
119                 for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
120             }
121         }
122     }
123 }sam;
124 
125 int main() {
126     read(Q);
127     scanf("%s",s);
128     len=strlen(s);
129     sam.init();
130     for(int i=0;i<len;i++) sam.insert(s[i]-'A');
131     while(Q--) {
132         scanf("%s",op);    
133         gets(mask);
134         len=chars.length();
135         if(op[0]=='A') {
136             for(int i=0;i<len;i++) 
137                 sam.insert(chars[i]-'A');
138         }
139         else {
140             int now=sam.rt;
141             for(int i=0;i<len;i++) {
142                 int c=chars[i]-'A';
143                 if(!sam.ch[now][c]) {
144                     puts("0");
145                     break;
146                 }
147                 now=sam.ch[now][c];
148                 if(i==len-1) {
149                     t.splay(now);
150                     mask^=t.sz[now];
151                     printf("%d
",t.sz[now]);
152                 }
153             }
154         }
155     }
156     return 0;
157 }
158 /* 
159 7
160 A
161 ADD BAABAC
162 ADD BAAB
163 QUERY BAAB
164 */
View Code
原文地址:https://www.cnblogs.com/Achenchen/p/8260791.html