• [BZOJ2555]SubString LCT+后缀自动机


    2555: SubString

    Time Limit: 30 Sec  Memory Limit: 512 MB
    Submit: 3253  Solved: 975
    [Submit][Status][Discuss]

    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

       

    Source

    Ctsc模拟赛By 洁妹

    显然我们要求当前子串子树的后缀结束结点个数。

    要在线实现,用lct维护sam

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<algorithm>
      7 #define maxn 1200000
      8 using namespace std;
      9 int mask;
     10 char st[3000005];
     11 string chars;
     12 void gets(int mask) {
     13     scanf("%s",st);
     14     chars=st;
     15     for(int j=0;j<chars.length();j++) {
     16         mask=(mask*131+j)%chars.length();
     17         char t=chars[j];
     18         chars[j]=chars[mask];
     19         chars[mask]=t;
     20     }
     21 }
     22 struct data {
     23     int last,cnt;
     24     int son[maxn][26],link[maxn],step[maxn];
     25     data() {last=cnt=1;}
     26     struct lct {
     27         int fa[maxn],s[maxn][2],v[maxn],tag[maxn];
     28         bool isroot(int x) {return s[fa[x]][1]!=x&&s[fa[x]][0]!=x;}
     29         void add(int x,int y){if(x) v[x]+=y,tag[x]+=y;}
     30         void pushdown(int x) {
     31             if(tag[x]) {
     32                 add(s[x][0],tag[x]);add(s[x][1],tag[x]);
     33                 tag[x]=0;
     34             }
     35         }
     36         void push(int x) {
     37             if(!isroot(x)) push(fa[x]);
     38             pushdown(x);
     39         }
     40         void rorate(int x) {
     41             int y=fa[x],z=fa[y];
     42             bool l=(s[y][1]==x),r=l^1;
     43             if(!isroot(y)) s[z][s[z][1]==y]=x;
     44             fa[x]=z;fa[y]=x;s[y][l]=s[x][r];
     45             fa[s[x][r]]=y;s[x][r]=y;
     46         }
     47         void splay(int x) {
     48             push(x);
     49             while(!isroot(x)) {
     50                 int y=fa[x],z=fa[y];
     51                 if(!isroot(y)) {
     52                     if(s[y][0]==x^s[z][0]==y) rorate(x);
     53                     else rorate(y);
     54                 }
     55                 rorate(x);
     56             }
     57         }
     58         void access(int x) {for(int t=0;x;t=x,x=fa[x]) {splay(x);s[x][1]=t;}}
     59         void link(int x,int y) {fa[x]=y;access(y);splay(y);add(y,v[x]);}
     60         void cut(int x) {access(x);splay(x);add(s[x][0],-v[x]);s[x][0]=fa[s[x][0]]=0;}
     61     }t;
     62     void extend(int c) {
     63         int p=last,np=last=++cnt;step[np]=step[p]+1;t.v[np]=1;
     64         while(p&&!son[p][c]) son[p][c]=np,p=link[p];
     65         if(!p) link[np]=1,t.link(np,1);
     66         else {
     67             int q=son[p][c];
     68             if(step[q]==step[p]+1) link[np]=q,t.link(np,q);
     69             else {
     70                 int nq=++cnt;
     71                 memcpy(son[nq],son[q],sizeof(son[q]));
     72                 link[nq]=link[q];t.link(nq,link[q]);
     73                 link[q]=link[np]=nq;
     74                 t.cut(q);t.link(np,nq);t.link(q,nq);
     75                 step[nq]=step[p]+1;
     76                 while(son[p][c]==q&&p) son[p][c]=nq,p=link[p];
     77             }
     78         }
     79     }
     80     void add() {
     81         gets(mask);
     82         int l=chars.length();
     83         for(int i=0;i<l;i++) extend(chars[i]-'A');
     84     }
     85     int query() {
     86         gets(mask);
     87         int p=1,l=chars.length();
     88         for(int i=0;i<l;i++) {
     89             p=son[p][chars[i]-'A'];if(!p) return 0;
     90         }
     91         t.splay(p);
     92         return t.v[p];
     93     }
     94 }sam;
     95 int main() {
     96     int Q;scanf("%d",&Q);
     97     scanf("%s",st+1);
     98     int len=strlen(st+1);
     99     for(int i=1;i<=len;i++) sam.extend(st[i]-'A');
    100     while(Q--) {
    101         char s[10];
    102         scanf("%s",s);
    103         if(s[0]=='A') sam.add();
    104         else {
    105             int ans=sam.query();
    106             printf("%d
    ",ans);
    107             mask^=ans;
    108         }
    109     }
    110 }
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    机器学习第二章复习
    机器学习第三章复习
    机器学习第四章复习
    第一次作业
    第二次作业
    第06组 Beta版本演示
    第06组 Beta冲刺(4/4)
    第06组 Beta冲刺(3/4)
    第06组 Beta冲刺(2/4)
    第06组 Beta冲刺(1/4)
  • 原文地址:https://www.cnblogs.com/wls001/p/8259650.html
Copyright © 2020-2023  润新知