BZOJ 2555: SubString 动态树+后缀自动机
2017-03-16 19:46
253 查看
首先,这是一道代码题,利用动态树维护后缀自动机的parent树,如果不是强制在线,可能会好写一点。
对于每个询问,找到被询问节点所在的right集合,集合大小即为答案。
注意,这里的LCT为有向的,写起来有些不一样。
对于每个询问,找到被询问节点所在的right集合,集合大小即为答案。
注意,这里的LCT为有向的,写起来有些不一样。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int maxn = 3050000; int n,m,mask,T; char s[maxn]; string chars; void gets(int mask) { scanf("%s",s); chars=s; for (int j=0;j<chars.length();j++) { mask=(mask*131+j)%chars.length(); char t=chars[j]; chars[j]=chars[mask]; chars[mask]=t; } } struct lct{ int w[maxn],ch[maxn][2],fa[maxn],tag[maxn],q[maxn]; bool rev[maxn]; bool isroot(int x){ return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; } void add(int x,int y) { if(x) { w[x]+=y;tag[x]+=y; } } void pushdown(int x) { int l=ch[x][0],r=ch[x][1]; if(tag[x]) { add(l,tag[x]),add(r,tag[x]); tag[x]=0; } } void rotate(int x) { int y=fa[x],z=fa[y],l=ch[y][1]==x,r=l^1; if(!isroot(y)) ch[z][ch[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; ch[y][l]=ch[x][r],ch[x][r]=y; } void splay(int x){ int top=0;q[++top]=x; for(int i=x;!isroot(i);i=fa[i]) q[++top]=fa[i];//cout<<q[i]<<endl; for(int i=top;i;i--) pushdown(q[i]); while(!isroot(x)) { int y=fa[x],z=fa[y]; if(!isroot(y)) { if(ch[y][0]==x^ch[z][0]==y) rotate(x); else rotate(y); } rotate(x); } } void access(int x) { int t=0; while(x) { splay(x);ch[x][1]=t;t=x;x=fa[x]; } } void link(int x,int y){ fa[x]=y;access(y);splay(y);add(y,w[x]); } void cut(int x){ access(x);splay(x);add(ch[x][0],-w[x]); fa[ch[x][0]]=0;ch[x][0]=0; } }t; struct sam{ int last,cnt; int a[maxn][27],fa[maxn],mx[maxn]; sam(){ last=++cnt; } void insert(int c) { int p=last,np=last=++cnt;t.w[np]=1;mx[np]=mx[p]+1; while(!a[p][c]&&p) a[p][c]=np,p=fa[p]; if(!p) fa[np]=1,t.link(np,1); else { int q=a[p][c]; if(mx[p]+1==mx[q]) fa[np]=q,t.link(np,q); else { int nq=++cnt;mx[nq]=mx[p]+1; memcpy(a[nq],a[q],sizeof(a[q])); fa[nq]=fa[q]; t.link(nq,fa[q]); fa[np]=fa[q]=nq; t.cut(q);t.link(np,nq);t.link(q,nq); while(a[p][c]==q) a[p][c]=nq,p=fa[p]; } } } void build(){ scanf("%s",s); int l=strlen(s); for(int i=0;i<l;i++) insert(s[i]-'A'); } void add(){ gets(mask); int l=chars.length(); for(int i=0;i<l;i++) insert(chars[i]-'A'); } int query(){ gets(mask); int l=chars.length(),p=1; for(int i=0;i<l;i++) if(!(p=a[p][chars[i]-'A'])) return 0; t.splay(p); return t.w[p]; } } sam; char op[5]; int main() { scanf("%d",&T); sam.build(); while(T--) { scanf("%s",op); if(op[0]=='A') sam.add(); else { int ans=sam.query(); printf("%d\n",ans); mask^=ans; } } return 0; }
相关文章推荐
- BZOJ2555:SubString 后缀自动机 LCT
- 后缀自动机 + LCT 【bzoj2555】SubString
- BZOJ2555 SubString 后缀自动机+LCT
- bzoj 2555: SubString 后缀自动机+LCT
- 【BZOJ2555】SubString 后缀自动机+LCT
- [后缀自动机 LCT] BZOJ 2555 SubString
- BZOJ 2555 Substring(后缀自动机+LCT子树维护)
- bzoj 2555: SubString 后缀自动机+LCT
- [BZOJ2555]SubString(后缀自动机+lct)
- 【bzoj2555】SubString 后缀自动机+LCT
- BZOJ 2555 SubString LCT 后缀自动机
- 【BZOJ2555】SubString(后缀自动机,Link-Cut Tree)
- BZOJ 2555 SubString 后缀自动机
- 【bzoj2555】SubString 后缀自动机+LCT
- 【BZOJ-2555】SubString 后缀自动机 + LinkCutTree
- 【BZOJ2555】SubString(后缀自动机,Link-Cut Tree)
- BZOJ 2555: SubString 后缀自动机+LCT
- 【BZOJ2555】SubString 后缀自动机 暴力
- 字符串(LCT,后缀自动机):BZOJ 2555 SubString
- BZOJ 2555 Substring 后缀自动机+Link-Cut-Tree