2555: SubString

Description

  
    懒得写背景了,给你一个字符串init,要求你支持两个操作
    
    (1):在当前字符串的后面插入一个字符串
    
    (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)
    
    你必须在线支持这些操作。
    

Input

    第一行一个数Q表示操作个数
    
    第二行一个字符串表示初始字符串init
    
    接下来Q行,每行2个字符串Type,Str 
    
    Type是ADD的话表示在后面插入字符串。
    
    Type是QUERY的话表示询问某字符串在当前字符串中出现了几次。
    
    为了体现在线操作,你需要维护一个变量mask,初始值为0
   
    
    读入串Str之后,使用这个过程将之解码成真正询问的串TrueStr。
    询问的时候,对TrueStr询问后输出一行答案Result
    然后mask = mask xor Result  
    插入的时候,将TrueStr插到当前字符串后面即可。

 

HINT:ADD和QUERY操作的字符串都需要解压
   

Output

 

Sample Input

2

A

QUERY B

ADD BBABBBBAAB

Sample Output


0

HINT

 

 40 % 的数据字符串最终长度 <= 20000,询问次数<= 1000,询问总长度<= 10000

    

100 % 的数据字符串最终长度 <= 600000,询问次数<= 10000,询问总长度<= 3000000


新加数据一组--2015.05.20

 
 
如果没有添加的操作的话,我们直接建立SAM然后查询r的大小即可。。。
但是因为我们要添加,所以可以想到我们每次实际上是把当前节点到根的路径上的r++,所以用lct。。。。
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<algorithm>
  6 #include<cmath>
  7 #define N 1200005
  8 #define inf 1000000000
  9 using namespace std;
 10 int mask;
 11 char s[3000005];
 12 string chars;
 13 void gets(int mask)
 14 {
 15     scanf("%s",s);
 16     chars=s;
 17     for (int j=0;j<chars.length();j++) 
 18     {
 19         mask=(mask*131+j)%chars.length();
 20         char t=chars[j];
 21         chars[j]=chars[mask];
 22         chars[mask]=t;
 23     }
 24 }
 25 struct lct
 26 {
 27     int top;
 28     int fa[N],c[N][2],w[N],tag[N],q[N];
 29     bool rev[N];
 30     void add(int x,int y){
 31         if(x)
 32         {
 33             w[x]+=y;tag[x]+=y;
 34         }
 35     }
 36     void pushdown(int x){
 37         int l=c[x][0],r=c[x][1];
 38         if(tag[x])
 39         {
 40             add(l,tag[x]);add(r,tag[x]);
 41             tag[x]=0;
 42         }
 43     }
 44     bool isroot(int x){
 45         return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
 46     }
 47     void rotate(int x){
 48         int y=fa[x],z=fa[y],l,r;
 49         if(c[y][0]==x)l=0;else l=1;r=l^1;
 50         if(!isroot(y))
 51         {
 52             if(c[z][0]==y)c[z][0]=x;
 53             else c[z][1]=x;
 54         }
 55         fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
 56         c[y][l]=c[x][r];c[x][r]=y;
 57     }
 58     void splay(int x){
 59         top=0;q[++top]=x;
 60         for(int i=x;!isroot(i);i=fa[i])
 61             q[++top]=fa[i];
 62         for(int i=top;i;i--)
 63             pushdown(q[i]);
 64         while(!isroot(x))
 65         {
 66             int y=fa[x],z=fa[y];
 67             if(!isroot(y))
 68             {
 69                 if(c[y][0]==x^c[z][0]==y)rotate(x);
 70                 else rotate(y);
 71             }
 72             rotate(x);
 73         }
 74     }
 75     void access(int x){
 76         for(int t=0;x;t=x,x=fa[x])
 77             splay(x),c[x][1]=t;
 78     }
 79     void link(int x,int f){
 80         fa[x]=f;access(f);splay(f);add(f,w[x]);
 81     }
 82     void cut(int x){
 83         access(x);splay(x);add(c[x][0],-w[x]);
 84         fa[c[x][0]]=0;c[x][0]=0;
 85     }        
 86 }t;
 87 struct sam
 88 {
 89     int l[N],fa[N],to[N][26];
 90     int cnt,last;
 91     int p,np,q,nq;
 92     sam(){
 93         last=++cnt;
 94     }
 95     void extend(int c){
 96         p=last;last=np=++cnt;t.w[np]=1;l[np]=l[p]+1;
 97         for(;p&&!to[p][c];p=fa[p])to[p][c]=np;
 98         if(!p)fa[np]=1,t.link(np,1);
 99         else
100         {
101             q=to[p][c];
102             if(l[p]+1==l[q])fa[np]=q,t.link(np,q);
103             else
104             {
105                 nq=++cnt;l[nq]=l[p]+1;
106                 memcpy(to[nq],to[q],sizeof(to[q]));
107                 fa[nq]=fa[q];
108                 t.link(nq,fa[q]);
109                 fa[np]=fa[q]=nq;
110                 t.cut(q);t.link(q,nq);t.link(np,nq);
111                 for(;to[p][c]==q;p=fa[p])to[p][c]=nq;
112             }
113         }
114     }
115     void build(){
116         scanf("%s",s);
117         int l=strlen(s);
118         for(int i=0;i<l;i++)
119             extend(s[i]-'A');
120     }
121     void add(){
122         gets(mask);
123         int l=chars.length();
124         for(int i=0;i<l;i++)
125             extend(chars[i]-'A');
126     }
127     int query(){
128         gets(mask);
129         int p=1,l=chars.length();
130         for(int i=0;i<l;i++)
131             if(!(p=to[p][chars[i]-'A']))return 0;
132         t.splay(p);
133         return t.w[p];
134     }
135 }sam;
136 int main()
137 {
138     int Q;scanf("%d",&Q);
139     sam.build();
140     while(Q--)
141     {
142         scanf("%s",s);
143         if(s[0]=='A')sam.add();
144         else 
145         {
146             int ans=sam.query();
147             printf("%d\n",ans);
148             mask^=ans;
149         }
150     }
151     return 0;
152 }
View Code

 

posted @ 2016-06-12 21:24  HTWX  阅读(142)  评论(0编辑  收藏  举报