【BZOJ2555】SubString(后缀自动机,LCT)

题意:给你一个字符串init,要求你支持两个操作

(1):在当前字符串的后面插入一个字符串

(2):询问字符串s在当前字符串中出现了几次?(作为连续子串)

你必须在线支持这些操作。

长度 <= 600000,询问次数<= 10000,询问总长度<= 3000000

思路:因为有加边,删边,加点操作,需要动态维护SAM中每个right集合的大小,所以使用LCT维护

需要维护根节点=1号点到每个结点路径上的和,因为固定了1号点为根节点所以不需要makeroot和rev标记

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 typedef pair<ll,int>P;
 11 #define N  1200010
 12 #define M  210000
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pi acos(-1)
 17 #define mem(a,b) memset(a,b,sizeof(a))
 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 20 #define lowbit(x) x&(-x)
 21 #define Rand (rand()*(1<<16)+rand())
 22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 23 #define ls p<<1
 24 #define rs p<<1|1
 25 
 26 const int MOD=1e9+7,inv2=(MOD+1)/2;
 27       double eps=1e-6;
 28       int INF=1<<29;
 29       ll inf=5e13;
 30       int dx[4]={-1,1,0,0};
 31       int dy[4]={0,0,-1,1};
 32 
 33 
 34 int mask;
 35 char s[3000010];
 36 string chars;
 37 
 38 int read()
 39 {
 40    int v=0,f=1;
 41    char c=getchar();
 42    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 43    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 44    return v*f;
 45 }
 46 
 47 void gets(int mask)
 48 {
 49     scanf("%s",s);
 50     chars=s;
 51     for(int j=0;j<chars.length();j++)
 52     {
 53         mask=(mask*131+j)%chars.length();
 54         char t=chars[j];
 55         chars[j]=chars[mask];
 56         chars[mask]=t;
 57     }
 58 }
 59 
 60 struct lct
 61 {
 62     int t[N][2],w[N],fa[N],q[N],rev[N],tag[N],top;
 63 
 64     void add(int x,int y)
 65     {
 66         if(x)
 67         {
 68             w[x]+=y;
 69             tag[x]+=y;
 70         }
 71     }
 72 
 73     int isroot(int x)
 74     {
 75         return ((t[fa[x]][0]!=x)&&(t[fa[x]][1]!=x));
 76     }
 77 
 78     void pushdown(int x)
 79     {
 80         int l=t[x][0],r=t[x][1];
 81         if(tag[x])
 82         {
 83             add(l,tag[x]);
 84             add(r,tag[x]);
 85             tag[x]=0;
 86         }
 87     }
 88 
 89     void rotate(int x)
 90     {
 91         int y=fa[x],z=fa[y];
 92         int l=(t[y][1]==x),r=l^1;
 93         if(!isroot(y)) t[z][t[z][1]==y]=x;
 94         fa[t[x][r]]=y,fa[y]=x,fa[x]=z;
 95         t[y][l]=t[x][r],t[x][r]=y;
 96     }
 97 
 98     void splay(int x)
 99     {
100         top=0;
101         q[++top]=x;
102         for(int i=x;!isroot(i);i=fa[i]) q[++top]=fa[i];
103         while(top) pushdown(q[top--]);
104         while(!isroot(x))
105         {
106             int y=fa[x],z=fa[y];
107             if(!isroot(y))
108             {
109                 if((t[y][0]==x)^(t[z][0]==y)) rotate(x);
110                  else rotate(y);
111             }
112             rotate(x);
113         }
114     }
115 
116     void access(int x)
117     {
118         for(int k=0;x;k=x,x=fa[x])
119         {
120             splay(x);
121             t[x][1]=k;
122         }
123     }
124 
125     void link(int x,int y)
126     {
127         fa[x]=y;
128         access(y);
129         splay(y);
130         add(y,w[x]);
131     }
132 
133     void cut(int x)
134     {
135         access(x);
136         splay(x);
137         add(t[x][0],-w[x]);
138         fa[t[x][0]]=0;
139         t[x][0]=0;
140     }
141 
142 }lct;
143 
144 struct sam
145 {
146     int cnt;
147     int F[N],ch[N][26];
148     int st[N],b[N],bl[N],c[N];
149     int p,np,q,nq;
150 
151     sam()
152     {
153         cnt=np=1;
154     }
155 
156     void extend(int x)
157     {
158         p=np; st[np=++cnt]=st[p]+1;
159         while(p&&!ch[p][x])
160         {
161             ch[p][x]=np;
162             p=F[p];
163         }
164         lct.w[np]=1;
165         if(!p) F[np]=1,lct.link(np,1);
166          else if(st[p]+1==st[q=ch[p][x]]) F[np]=q,lct.link(np,q);
167           else
168           {
169               st[nq=++cnt]=st[p]+1;
170               memcpy(ch[nq],ch[q],sizeof ch[q]);
171               F[nq]=F[q];
172               lct.link(nq,F[q]);
173               F[np]=F[q]=nq;
174               lct.cut(q);
175               lct.link(q,nq);
176               lct.link(np,nq);
177               while(ch[p][x]==q)
178               {
179                     ch[p][x]=nq;
180                     p=F[p];
181               }
182           }
183     }
184 
185     void build()
186     {
187         scanf("%s",s);
188         int n=strlen(s);
189         rep(i,0,n-1) extend(s[i]-'A');
190     }
191 
192     void add()
193     {
194         gets(mask);
195         int n=chars.length();
196         rep(i,0,n-1) extend(chars[i]-'A');
197     }
198 
199     int query()
200     {
201         gets(mask);
202         int p=1,n=chars.length();
203         rep(i,0,n-1)
204         {
205             p=ch[p][chars[i]-'A'];
206             if(!p) return 0;
207         }
208         lct.splay(p);
209         return lct.w[p];
210     }
211 
212 }sam;
213 
214 
215 int main()
216 {
217     int Q;
218     scanf("%d",&Q);
219     sam.build();
220     while(Q--)
221     {
222         scanf("%s",s);
223         if(s[0]=='A') sam.add();
224          else
225          {
226             int ans=sam.query();
227             printf("%d\n",ans);
228             mask^=ans;
229          }
230     }
231     return 0;
232 }
233 

 

posted on 2019-09-12 19:58  myx12345  阅读(203)  评论(0编辑  收藏  举报

导航