[后缀自动机 LCT] BZOJ 2555 SubString
2017-01-28 21:26
423 查看
构建后缀自动机 parent树会改变形态 这样|right(x)|也会发生变化
我们用LCT大力维护一发就好了
我们用LCT大力维护一发就好了
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } inline int read(char *s){ char c=nc(); int len=0; for (;!(c>='A' && c<='Z');c=nc()) if (c==EOF) return 0; for (;c>='A' && c<='Z';s[++len]=c,c=nc()); s[++len]=0; return len-1; } const int N=1200005; struct Splay{ #define ls ch[x][0] #define rs ch[x][1] int val ,ch [2],fat ,add ; inline int dir(int x){return ch[fat[x]][1]==x;} inline int isroot(int x){return ch[fat[x]][0]!=x&&ch[fat[x]][1]!=x;} inline void mark(int x,int v){add[x]+=v,val[x]+=v;} inline void pushdown(int x){ if (add[x]!=0){ if (ls) mark(ls,add[x]); if (rs) mark(rs,add[x]); add[x]=0; } } void relax(int x){if (!isroot(x)) relax(fat[x]);pushdown(x);} void rotate(int x){ int y=fat[x],z=fat[y],nx=dir(x),ny=dir(y),isrt=isroot(y); fat[ch[x][!nx]]=y,ch[y][nx]=ch[x][!nx]; fat[x]=z;if (!isrt) ch[z][ny]=x; fat[y]=x,ch[x][!nx]=y; } void splay(int x){ relax(x); while (!isroot(x)){ int y=fat[x]; if (isroot(y)) rotate(x); else if (dir(x)==dir(y)) rotate(y),rotate(x); else rotate(x),rotate(x); } } void access(int x){ for (int p=0;x;x=fat[x]) splay(x),rs=p,p=x; } void link(int x,int f){ fat[x]=f,access(f),splay(f),mark(f,val[x]); } void cut(int x){ access(x),splay(x),mark(ls,-val[x]); fat[ls]=0,ls=0; } #undef ls #undef rs }LCT; struct state{ int len,link,next[26]; }st ; int ncnt,last; inline void Extend(char c){ int cur=++ncnt,p; c-='A'; st[cur].len=st[last].len+1; LCT.val[cur]=1; for (p=last;p!=-1 && !st[p].next[c];p=st[p].link) st[p].next[c]=cur; if (p==-1) st[cur].link=1,LCT.link(cur,1); else{ int q=st[p].next[c]; if (st[q].len==st[p].len+1) st[cur].link=q,LCT.link(cur,q); else{ int nq=++ncnt; st[nq].len=st[p].len+1; st[nq].link=st[q].link; LCT.cut(q); LCT.link(nq,st[q].link); memcpy(st[nq].next,st[q].next,sizeof(st[q].next)); for (;p!=-1 && st[p].next[c]==q;p=st[p].link) st[p].next[c]=nq; st[q].link=st[cur].link=nq; LCT.link(q,nq); LCT.link(cur,nq); } } last=cur; } int n; char S ; inline void decode(int mask){ for (int i=1;i<=n;i++){ mask=(mask*131+i-1)%n; swap(S[i],S[mask+1]); } } int main(){ int Q,mask=0; char order[15]; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(Q); n=read(S); ncnt=last=1; st[1].link=-1; for (int i=1;i<=n;i++) Extend(S[i]); while (Q--){ read(order); n=read(S); decode(mask); if (order[1]=='A'){ for (int i=1;i<=n;i++) Extend(S[i]); }else{ int p=1,ans=-1; for (int i=1;i<=n;i++){ if (!st[p].next[S[i]-'A']) { ans=0; break; } p=st[p].next[S[i]-'A']; } if (ans==-1) LCT.splay(p),ans=LCT.val[p]; printf("%d\n",ans); mask^=ans; } } return 0; }
相关文章推荐
- 【bzoj2555】SubString 后缀自动机+LCT
- bzoj 2555: SubString 后缀自动机+LCT
- bzoj 2555 SubString 后缀自动机 LCT
- BZOJ 2555: SubString [后缀自动机 LCT]
- BZOJ 2555: SubString 后缀自动机 LCT
- bzoj2555 SubString(后缀自动机+LCT)
- [后缀自动机][LCT] BZOJ 2555: SubString
- bzoj 2555: SubString 后缀自动机+LCT
- [BZOJ2555]SubString(后缀自动机+LCT)
- BZOJ2555 SubString 后缀自动机+LCT
- BZOJ 2555: SubString 后缀自动机+LCT
- bzoj 2555: SubString 后缀自动机+lct
- BZOJ2555 SubString 【后缀自动机 + LCT】
- [BZOJ2555]-SubString-后缀自动机+LCT维护parent树
- 字符串(LCT,后缀自动机):BZOJ 2555 SubString
- [BZOJ2555][LCT][后缀自动机]SubString
- 【bzoj2555】SubString LCT+后缀自动机
- 后缀自动机 + LCT 【bzoj2555】SubString
- [BZOJ2555]SubString(后缀自动机+lct)
- BZOJ 2555 SubString 后缀自动机+LCT