【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
null