zoukankan      html  css  js  c++  java
  • 【BZOJ 2555】 2555: SubString (SAM+LCT)

    2555: SubString

    Time Limit: 30 Sec  Memory Limit: 512 MB
    Submit: 2548  Solved: 762

    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

    【分析】

      一开始都没想着用LCT,后来发现我的SAM的right数组一直都是要逆拓扑序求的。

      在线的话,还要在线维护。把pre边看成一棵树,就是要支持link,cut操作的,求子树和的东西。

      其实LCT我只会做路径的,不会做子树了。看了hzwer的代码。【然后好像是,其实也是维护了路径,就是link x和f 的时候就是把f到根的路径都加上val[x]

      【ORZ欧颓果说用splay维护dfs序也可以啊?

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 #define Maxn 600010
      8 #define Maxl 3000010
      9 
     10 struct node
     11 {
     12     int pre,son[30],step;
     13 }t[Maxn*2];
     14 
     15 struct nnode
     16 {
     17     int son[2],fa,val,laz;
     18     nnode() {son[0]=son[1]=fa=val=laz=0;}
     19 }tr[Maxn*2];
     20 
     21 char s[Maxl];
     22 void init(int mask)
     23 {
     24     scanf("%s",s);
     25     int l=strlen(s);
     26     for(int i=0;i<l;i++)
     27     {
     28         mask=(mask*131+i)%l;
     29         swap(s[i],s[mask]);
     30     }
     31 }
     32 
     33 struct lct
     34 {
     35     void add(int x,int y)
     36     {
     37         if(x) tr[x].val+=y,tr[x].laz+=y;
     38     }
     39     bool is_root(int x)
     40     {
     41         return tr[tr[x].fa].son[0]!=x&&tr[tr[x].fa].son[1]!=x;
     42     }
     43     bool pushdown(int x)
     44     {
     45         int lc=tr[x].son[0],rc=tr[x].son[1];
     46         if(tr[x].laz)
     47         {
     48             add(lc,tr[x].laz);add(rc,tr[x].laz);
     49             tr[x].laz=0;
     50         }
     51     }
     52     void rot(int x)
     53     {
     54         int fa=tr[x].fa,yy=tr[fa].fa;
     55         int w=tr[tr[x].fa].son[0]==x;
     56         
     57         if(!is_root(fa))
     58         {
     59             if(tr[yy].son[0]==fa) tr[yy].son[0]=x;
     60             else tr[yy].son[1]=x;
     61         }tr[x].fa=yy;
     62         
     63         tr[fa].son[1-w]=tr[x].son[w];
     64         tr[tr[x].son[w]].fa=fa;
     65         
     66         tr[x].son[w]=fa;
     67         tr[fa].fa=x;
     68         //upd(fa);//upd(x);
     69     }
     70     int q[2*Maxn];
     71     void pre(int x)
     72     {
     73         int tp=0;
     74         while(!is_root(x)) q[++tp]=x,x=tr[x].fa;
     75         q[++tp]=x;
     76         for(int i=tp;i>=1;i--) pushdown(q[i]);
     77     }
     78     void splay(int x)
     79     {
     80         pre(x);
     81         while(!is_root(x))
     82         {
     83             int fa=tr[x].fa,yy=tr[fa].fa;
     84             if(!is_root(fa))
     85             {
     86                 if((tr[yy].son[0]==fa)==(tr[fa].son[0]==x)) rot(fa);
     87                 else rot(x);
     88             }
     89             rot(x);
     90         }//upd(x);
     91     }
     92     void access(int x)
     93     {
     94         int t=0;
     95         while(x)
     96         {
     97             splay(x);
     98             tr[x].son[1]=t;
     99             t=x;
    100             x=tr[x].fa;
    101         }
    102     }
    103     /*void split(int x,int y)
    104     {
    105         make_root(x);
    106         access(y);
    107         splay(y);
    108     }*/
    109     void link(int x,int f)
    110     {
    111         tr[x].fa=f;
    112         access(f);
    113         splay(f);
    114         add(f,tr[x].val);
    115     }
    116     void cut(int x)
    117     {
    118         access(x);splay(x);
    119         add(tr[x].son[0],-tr[x].val);
    120         tr[tr[x].son[0]].fa=0;
    121         tr[x].son[0]=0;
    122     }
    123 }lct;
    124 
    125 int mask;
    126 struct sam
    127 {
    128     int last,tot;
    129     void extend(int k)
    130     {
    131         int np=++tot,p=last;
    132         t[np].step=t[p].step+1;
    133         tr[np].val=1;
    134         while(p&&!t[p].son[k])
    135         {
    136             t[p].son[k]=np;
    137             p=t[p].pre;
    138         }
    139         if(!p) t[np].pre=1,lct.link(np,1);
    140         else
    141         {
    142             int q=t[p].son[k];
    143             if(t[q].step==t[p].step+1) t[np].pre=q,lct.link(np,q);
    144             else
    145             {
    146                 int nq=++tot;//upd(tot);
    147                 t[nq].step=t[p].step+1;
    148                 memcpy(t[nq].son,t[q].son,sizeof(t[nq].son));
    149                 t[nq].pre=t[q].pre;
    150                 lct.link(nq,t[nq].pre);
    151                 t[q].pre=t[np].pre=nq;
    152                 lct.cut(q);lct.link(q,nq);lct.link(np,nq);
    153                 while(p&&t[p].son[k]==q)
    154                 {
    155                     t[p].son[k]=nq;
    156                     p=t[p].pre;
    157                 }
    158             }
    159         }
    160         last=np;
    161     }
    162     void add()
    163     {
    164         init(mask);
    165         int l=strlen(s);
    166         for(int i=0;i<l;i++) extend(s[i]-'A'+1);
    167     }
    168     int query()
    169     {
    170         init(mask);
    171         int nw=1,l=strlen(s);
    172         for(int i=0;i<l;i++)
    173         {
    174             int ind=s[i]-'A'+1;
    175             if(!t[nw].son[ind]) return 0;
    176             nw=t[nw].son[ind];
    177         }
    178         lct.splay(nw);
    179         return tr[nw].val;
    180     }
    181 }sam;
    182 
    183 char ss[10];
    184 
    185 int main()
    186 {
    187     int q;
    188     scanf("%d",&q);
    189     sam.tot=sam.last=1;
    190     scanf("%s",s);
    191     int l=strlen(s);
    192     for(int i=0;i<l;i++) sam.extend(s[i]-'A'+1);
    193     while(q--)
    194     {
    195         scanf("%s",ss);
    196         if(ss[0]=='A') sam.add();
    197         else
    198         {
    199             int ans=sam.query();
    200             printf("%d
    ",ans);
    201             mask^=ans;
    202         }
    203     }
    204     return 0;
    205 }
    View Code

    2017-04-19 07:48:14

  • 相关阅读:
    c# winform DataGridView导出数据到Excel中,可以导出当前页和全部数据
    水晶报表动态加载图片(签名)
    第1章 开启Threejs之旅(一)
    Python中@contextmanager的用法
    Systemd
    Python中with的用法
    systemctl的配置和使用
    /*CS5460_Note_1*/
    Just try the code
    MCP2515无BUG版本驱动(C文件)
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6731448.html
Copyright © 2011-2022 走看看