bzoj 2555: SubString 后缀自动机+lct

来源:互联网 发布:淘宝买家权重信用查询 编辑:程序博客网 时间:2024/06/07 13:58

        WC前鏼一题求平安qaq,,,rp++

        首先求出后缀自动机,然后相当于统计一个点的right集合的大小;转化为一个树动态加点和增减边的lct问题,然后就码码码就好了。

AC代码如下:

#include<bits/stdc++.h>#define N 1200005#define isrt(x) (c[fa[x]][0]!=x && c[fa[x]][1]!=x)using namespace std;int mask,tp,q[N],fa[N],c[N][2],tag[N],num[N]; char s[N];void mdy(int x,int y){tag[x]+=y; num[x]+=y;}void pushdn(int x){if (tag[x]){mdy(c[x][0],tag[x]); mdy(c[x][1],tag[x]); tag[x]=0;}}void rotate(int x){int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;if (!isrt(y)) c[z][c[z][1]==y]=x;fa[x]=z; fa[y]=x; fa[c[x][r]]=y;c[y][l]=c[x][r]; c[x][r]=y;}void splay(int x){int i,y,z; q[tp=1]=x;for (i=x; !isrt(i); i=fa[i]) q[++tp]=fa[i];while (tp) pushdn(q[tp--]);for (; !isrt(x); rotate(x)){y=fa[x]; z=fa[y];if (!isrt(y)) rotate((c[z][0]==y ^ c[y][0]==x)?x:y);}}void acss(int x){int y=0;for (; x; y=x,x=fa[x]){splay(x); c[x][1]=y;}}void link(int x,int y){fa[x]=y; acss(x); splay(x);}void cut(int x,int y){acss(y); splay(y); fa[x]=c[y][1]=0;}struct sam_node{int tot,last,ch[N][26],fa[N],len[N];sam_node(){ tot=last=1; }void ins(int c){int np=++tot,p=last; len[np]=len[p]+1; last=tot;for (; p && !ch[p][c]; p=fa[p]) ch[p][c]=np;if (!p){fa[np]=1; link(np,1);} else{int q=ch[p][c];if (len[p]+1==len[q]){fa[np]=q; link(np,q);} else{int nq=++tot; len[nq]=len[p]+1; memcpy(ch[nq],ch[q],sizeof(ch[q]));splay(q); num[nq]=num[q];cut(q,fa[q]); fa[nq]=fa[q]; link(nq,fa[q]);fa[q]=fa[np]=nq; link(q,nq); link(np,nq);for (; p && ch[p][c]==q; p=fa[p]) ch[p][c]=nq;}}acss(np); splay(np); mdy(np,1);}void qry(){int now=1,len=strlen(s),i;for (i=0; i<len; i++) now=ch[now][s[i]-'A'];if (!now){ puts("0"); return; }splay(now); printf("%d\n",num[now]); mask^=num[now];}}sam;void pwk(int mask){int i,len=strlen(s);for (i=0; i<len; i++){mask=(mask*131+i)%len; swap(s[i],s[mask]);}}int main(){int cas,i; scanf("%d",&cas);scanf("%s",s);int len=strlen(s); char ch[10];for (i=0; i<len; i++) sam.ins(s[i]-'A');while (cas--){scanf("%s%s",ch,s); pwk(mask);if (ch[0]=='A'){len=strlen(s);for (i=0; i<len; i++) sam.ins(s[i]-'A');} else sam.qry();}return 0;}


by lych

2017.2.7

0 0
原创粉丝点击