bzoj2555

来源:互联网 发布:中国石油库存数据 编辑:程序博客网 时间:2024/06/16 15:35
开始时间:19:40

完成时间:21:00

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2555

题目大意:(1):在当前字符串的后面插入一个字符串
    
        (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)

题解:最近在写后缀自动机,求一个字符串中出现了几次就相当与其right集合大小,直接上parent树,因为后缀自动机构造特性,可能在parent树改变边,于是用lct维护;

代码:

  1 #include<algorithm>  2 #include<iostream>  3 #include<cstring>  4 #include<cstdio>  5 #include<cmath>  6 #define maxn 1200005  7 #define maxl 3000005  8 using namespace std;  9 int q,n,tot,root,last,mark,m,ri[maxn],lazy[maxn]; 10 char st[maxl]; 11 char ss[20]; 12 struct data{ 13     int fa[maxn],son[maxn][2]; 14     int isroot(int x) {return (son[fa[x]][0]!=x && son[fa[x]][1]!=x);} 15     int which(int x){return son[fa[x]][1]==x;} 16     void change(int x,int k){ ri[x]+=k; lazy[x]+=k;} 17     void pushdown(int x) 18     { 19         if (!lazy[x]) return; 20         if (son[x][1]) change(son[x][1],lazy[x]); 21         if (son[x][0]) change(son[x][0],lazy[x]); 22         lazy[x]=0; 23     } 24     void relax(int x){if (!isroot(x)) relax(fa[x]); pushdown(x);} 25     void turn(int x){ 26         int y=fa[x],wx=which(x),wy=which(y); 27         if (!isroot(y)) son[fa[y]][wy]=x; fa[x]=fa[y]; 28         son[y][wx]=son[x][1-wx]; fa[son[x][1-wx]]=y;  29         son[x][1-wx]=y; fa[y]=x; 30     } 31     void splay(int x) 32     { 33         relax(x); 34         while (!isroot(x)) 35         { 36             if (isroot(fa[x])) turn(x); 37             else if (which(x)==which(fa[x])) turn(fa[x]),turn(x); 38             else turn(x),turn(x); 39         } 40     } 41     void access(int x) 42     { 43         for (int p=0; x; x=fa[x]){ splay(x); son[x][1]=p; p=x;} 44     } 45     void link(int x,int y){ 46         fa[x]=y; access(y); splay(y); change(y,ri[x]); 47     } 48     void cut(int x) 49     { 50         access(x); splay(x); change(son[x][0],-ri[x]); fa[son[x][0]]=0; son[x][0]=0; 51     } 52 }lct; 53 struct date{ 54     int fa[maxn],son[maxn][26],val[maxn]; 55     void prepare(){root=tot=last=1;} 56     int newnode(int x){val[++tot]=x; return tot;} 57     void extend(int x) 58     { 59         int p=last,np=newnode(val[p]+1);ri[np]=1;last=np; 60         for (; p&&!son[p][x]; p=fa[p]) son[p][x]=np;  61         if (!p) fa[np]=root,lct.link(np,root); 62         else 63         { 64             int q=son[p][x]; 65             if (val[q]==val[p]+1){fa[np]=q; lct.link(np,q);} 66             else 67             { 68                 int nq=newnode(val[p]+1);ri[nq]=0; 69                 memcpy(son[nq],son[q],sizeof(son[q])); 70                 fa[nq]=fa[q]; lct.cut(q),lct.link(nq,fa[nq]); 71                 fa[q]=fa[np]=nq; lct.link(q,nq),lct.link(np,nq); 72                 for (; p && son[p][x]==q; p=fa[p]) son[p][x]=nq;  73             } 74         } 75     } 76     void build() 77     {for (int i=1; i<=m; i++) extend(st[i]-'A');} 78     void query(){ 79         int x,y; 80         bool can=1; 81         x=root; 82         for (int i=1;i<=m;i++){ 83             y=st[i]-'A'; 84             if (!son[x][y]){ 85                 can=0; 86                 break; 87             }else{ 88                 x=son[x][y]; 89             } 90         } 91         if (can==0||x==root) puts("0"); 92         else{ 93             lct.splay(x); 94             printf("%d\n",ri[x]),mark^=ri[x]; 95         } 96     } 97 }SAM; 98 void unzip(){ 99     int temp=mark;100     for (int i=1;i<=m;i++){101         temp=(temp*131+i-1)%m+1;102         char t=st[i]; st[i]=st[temp],st[temp]=t,temp--;103     }104 }105 int main()106 {107     scanf("%d\n",&q);mark=0;108     scanf("%s",st+1); m=strlen(st+1);109     SAM.prepare();110     SAM.build();111     for (int i=1; i<=q; i++)112     {113         scanf("%s",ss);scanf("%s",st+1); m=strlen(st+1);unzip(); 114         if (ss[0]=='A') SAM.build();115         else SAM.query();116     }117 }
View Code

 

0 0