BZOJ2555:SubString——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2555
(1):在当前字符串的后面插入一个字符串(2):询问字符串s在当前字符串中出现了几次?(作为连续子串)你必须在线支持这些操作。
参考:https://www.cnblogs.com/zcysky/p/6851553.html
动态加字符串很容易想到后缀自动机。
如果暴力更新size(或者叫right?)以前是能过的,现在过不了。
但其实parent树本身就是树,用lct维护一下就可做了。
(树根和朝向一定所以不用rev当然用了也没人拦你。)
(很gg,更新lct需要打标记pushdown而不是upt,cut的节点也不要搞错了。)
#include<cstdio> #include<iostream> #include<queue> #include<cstring> #include<algorithm> #include<cctype> using namespace std; typedef long long ll; const int N=1200005; struct tree{ int a[26],fa,l; }ti[N]; char s[3000005],ch[300]; int last,cnt; int a[N],w[N],size[N],tag[N]; int n,m,r,fa[N],tr[N][2],q[N]; inline void add(int x,int y){if(x)tag[x]+=y,size[x]+=y;} inline bool get(int x){ return tr[fa[x]][1]==x; } inline bool isroot(int x){ if(!fa[x])return 1; return tr[fa[x]][0]!=x&&tr[fa[x]][1]!=x; } inline void push(int x){ if(!tag[x])return; add(tr[x][0],tag[x]); add(tr[x][1],tag[x]); tag[x]=0; } inline void rotate(int x){ int y=fa[x],z=fa[y],which=get(x); if(z&&!isroot(y))tr[z][tr[z][1]==y]=x; tr[y][which]=tr[x][which^1];fa[tr[y][which]]=y; fa[y]=x;tr[x][which^1]=y;fa[x]=z; } inline void splay(int x){ q[r=0]=x; for(int y=x;!isroot(y);y=fa[y])q[++r]=fa[y]; for(int i=r;i>=0;i--)push(q[i]); while(!isroot(x)){ if(!isroot(fa[x])) rotate((get(x)==get(fa[x])?fa[x]:x)); rotate(x); } } inline void access(int x){ for(int y=0;x;y=x,x=fa[x]){ splay(x);tr[x][1]=y; if(y)fa[y]=x; } } inline void link(int x,int y){ fa[x]=y;access(y);splay(y);add(y,size[x]); } inline void cut(int x){ access(x);splay(x);add(tr[x][0],-size[x]); fa[tr[x][0]]=0;tr[x][0]=0; } inline void insert(int c){ int p=last,np=++cnt; last=np;ti[np].l=ti[p].l+1;size[np]=1; for(;p&&!ti[p].a[c];p=ti[p].fa)ti[p].a[c]=np; if(!p){ ti[np].fa=1; link(np,1); } else{ int q=ti[p].a[c]; if(ti[p].l+1==ti[q].l){ ti[np].fa=q; link(np,q); } else{ int nq=++cnt;ti[nq].l=ti[p].l+1; memcpy(ti[nq].a,ti[q].a,sizeof(ti[q].a)); cut(q); link(nq,ti[q].fa);link(q,nq);link(np,nq); ti[nq].fa=ti[q].fa;ti[q].fa=ti[np].fa=nq; for(;p&&ti[p].a[c]==q;p=ti[p].fa)ti[p].a[c]=nq; } } } inline int query(int len){ int now=1; for(int i=0;i<len;i++){ if(ti[now].a[s[i]-'A']){ now=ti[now].a[s[i]-'A']; }else return 0; } access(now);splay(now); return size[now]; } int main(){ last=cnt=1; int q,mask=0,len,res; scanf("%d%s",&q,s); len=strlen(s); for(int i=0;i<len;i++)insert(s[i]-'A'); while(q--){ scanf("%s%s",ch,s); len=strlen(s);res=mask; for(int i=0;i<len;i++){ res=(res*131+i)%len; swap(s[i],s[res]); } if(ch[0]=='A'){ for(int i=0;i<len;i++)insert(s[i]-'A'); }else{ int tmp=query(len); printf("%d\n",tmp); mask^=tmp; } } return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++