bzoj2555 SubString
题接:
没有任何意义的LCT+SAM。
没有题解
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 600050 int n,m,mask,len; char s[N]; void decode(int msk) { len = strlen(s); for(int i=0;i<len;i++) { msk = (msk*131+i)%len; swap(s[i],s[msk]); } } struct LCT { int ch[2*N][2],fa[2*N],s[2*N],sx[2*N],v[2*N]; bool rt[2*N],res[2*N]; void update(int u){s[u]=sx[u]+s[ch[u][0]]+s[ch[u][1]]+v[u];} void reser(int u) { res[u]^=1; swap(ch[u][0],ch[u][1]); } void pushdown(int u) { if(res[u]) { res[u]=0; reser(ch[u][0]); reser(ch[u][1]); } } int tmp[2*N],tl; void down(int u) { tl=0; tmp[++tl]=u; while(!rt[u])u=fa[u],tmp[++tl]=u; while(tl)pushdown(tmp[tl]),tl--; } void rotate(int x) { int y = fa[x],k = (ch[y][1]==x); if(rt[y])rt[y]=0,rt[x]=1; else ch[fa[y]][ch[fa[y]][1]==y]=x; fa[x]=fa[y]; ch[y][k] = ch[x][!k],fa[ch[x][!k]]=y; ch[x][!k] = y,fa[y] = x; update(y),update(x); } void splay(int x) { down(x); while(!rt[x]) { int y = fa[x],z = fa[y]; if(!rt[y]) (ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y); rotate(x); } } void access(int x) { int y = 0; while(x) { splay(x); sx[x]+=(s[ch[x][1]]-s[y]); rt[ch[x][1]]=1,rt[y]=0; ch[x][1]=y; update(x); y=x,x=fa[x]; } } void link(int x,int y) { access(y); splay(y); fa[x]=y,sx[y]+=s[x]; update(y); } void cut(int x,int y) { access(y); splay(y); fa[x]=ch[y][0]=0; rt[x]=1; update(y); } int query(int x) { access(x); splay(x); return v[x]+sx[x]; } void clear(int x,int typ) { fa[x]=ch[x][0]=ch[x][1]=sx[x]=0; rt[x]=1;res[x]=0; s[x]=v[x]=typ; } }tr; struct node { int pre,len,trs[28]; }p[2*N]; struct SAM { int las,tot; SAM(){las=tot=1;} void insert(int c) { int np,nq,lp,lq; np=++tot; tr.clear(np,1); p[np].len = p[las].len+1; for(lp=las;lp&&!p[lp].trs[c];lp=p[lp].pre) p[lp].trs[c] = np; if(!lp)p[np].pre = 1,tr.link(np,1); else { lq = p[lp].trs[c]; if(p[lq].len==p[lp].len+1)p[np].pre = lq,tr.link(np,lq); else { nq = ++tot; tr.clear(nq,0); p[nq] = p[lq]; tr.link(nq,p[nq].pre); p[nq].len = p[lp].len+1; tr.cut(p[lq].pre,lq); tr.link(lq,nq);tr.link(np,nq); p[lq].pre = p[np].pre = nq; while(p[lp].trs[c]==lq) { p[lp].trs[c] = nq; lp = p[lp].pre; } } } las = np; } }sam; int main() { scanf("%d%s",&m,s); len = strlen(s); tr.clear(1,0); for(int i=0;i<len;i++) sam.insert(s[i]-'A'+1); while(m--) { scanf("%s",s); if(s[0]=='Q') { scanf("%s",s); decode(mask); int u = 1; for(int i=0;i<len;i++) { u = p[u].trs[s[i]-'A'+1]; if(!u)break; } int ans = 0; if(u)ans = tr.query(u); mask^=ans; printf("%d\n",ans); }else { scanf("%s",s); decode(mask); for(int i=0;i<len;i++) sam.insert(s[i]-'A'+1); } } return 0; }