• bzoj2555 SubString


    后缀自动机+LCT维护parent树

    其实就是要求一个动态添加的right集合大小,每次添加改变的只有last以及他的parent链上的点,我们还要维护动态删边加边,于是LCT就是最好的选择。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 #define N 1205000
      7 using namespace std;
      8 char s[N<<3],opt[10];
      9 int n,m,mask;
     10 struct Node {
     11     Node *ch[2],*fa;
     12     int id,val,lazy;
     13     void update(int x){val+=x;lazy+=x;}
     14     void pushdown();
     15     Node(){};
     16 }*null=new Node(),tree[N];
     17 void Node :: pushdown(){
     18     if(lazy){
     19         if(ch[0]!=null)ch[0]->update(lazy);
     20         if(ch[1]!=null)ch[1]->update(lazy);
     21         lazy=0;
     22     }
     23 }
     24 void init(){
     25     null->ch[0]=null->ch[1]=null->fa=null;
     26     null->id=null->val=null->lazy=0;
     27     for(int i=1;i<N;i++){
     28         tree[i].ch[0]=tree[i].ch[1]=tree[i].fa=null;
     29         tree[i].lazy=tree[i].val=0;tree[i].id=i;
     30     }
     31 }
     32 void rotate(Node *x){
     33     Node *y=x->fa,*z=y->fa;
     34     int w=y->ch[1]==x;
     35     x->ch[w^1]->fa=y;y->ch[w]=x->ch[w^1];
     36     y->fa=x;x->ch[w^1]=y;
     37     if(z->ch[0]==y)z->ch[0]=x;
     38     if(z->ch[1]==y)z->ch[1]=x;
     39     x->fa=z;
     40 }
     41 bool isroot(Node *x){
     42     return x->fa->ch[0]!=x&&x->fa->ch[1]!=x;
     43 }
     44 int get(Node *x){
     45     if(x->fa->ch[0]==x)return 0;
     46     if(x->fa->ch[1]==x)return 1;
     47     return -1;
     48 }
     49 void pushdown(Node *x){
     50     if(!isroot(x))
     51         pushdown(x->fa);
     52     x->pushdown();
     53 }
     54 void splay(Node *x){
     55     Node *y;
     56     pushdown(x);
     57     while(!isroot(x)){
     58         y=x->fa;
     59         if(!isroot(y)){
     60             if(get(y)==get(x))rotate(y);
     61             else rotate(x);
     62         }rotate(x);
     63     }
     64 }
     65 void access(Node *x){
     66     Node *y=null;
     67     while(x!=null){
     68         splay(x);
     69         x->ch[1]=y;
     70         y=x;x=x->fa;
     71     }
     72 }
     73 void cut(Node *x,Node *y){
     74     access(y);splay(y);
     75     y->ch[0]=x->fa=null;
     76 }
     77 void link(Node *x,Node *y){
     78     access(y);splay(y);
     79     x->fa=y;
     80 }
     81 void update(Node *x){
     82     access(x);
     83     splay(x);
     84     x->update(1);
     85 }
     86 void query(Node *x){
     87     access(x);
     88     splay(x);
     89     printf("%d
    ",x->val);
     90     mask^=x->val;
     91 }
     92 int last,tot,mx[N],par[N],ch[N][26];
     93 void add(int c){
     94     int p=last,np=++tot;mx[np]=mx[p]+1;
     95     for(;p&&!ch[p][c];p=par[p])ch[p][c]=np;
     96     if(!p)par[np]=1;
     97     else{
     98         int q=ch[p][c];
     99         if(mx[q]==mx[p]+1)par[np]=q;
    100         else{
    101             int nq=++tot;
    102             access(&tree[q]);
    103             splay(&tree[q]);
    104             tree[nq].val=tree[q].val;
    105             link(&tree[nq],&tree[par[q]]);
    106             cut(&tree[par[q]],&tree[q]);
    107             link(&tree[q],&tree[nq]);
    108             mx[nq]=mx[p]+1;
    109             par[nq]=par[q];
    110             memcpy(ch[nq],ch[q],sizeof ch[nq]);
    111             par[q]=par[np]=nq;
    112             for(;p&&ch[p][c]==q;p=par[p])ch[p][c]=nq;
    113         }
    114     }
    115     link(&tree[np],&tree[par[np]]);
    116     update(&tree[np]);
    117     last=np;
    118 }
    119 void gets(int x){
    120     scanf("%s",s);
    121     n=strlen(s);
    122     for(int j=0;j<n;j++){
    123         x=(x*131+j)%n;
    124         char t=s[j];s[j]=s[x];s[x]=t;
    125     }
    126 }
    127 void dfs(int v,int x){
    128     if(x==n){query(&tree[v]);return ;}
    129     if(!ch[v][s[x]-'A']){puts("0");return ;}
    130     else dfs(ch[v][s[x]-'A'],x+1);
    131 }
    132 int main(){
    133     init();
    134     last=++tot;
    135     scanf("%d",&m);
    136     scanf("%s",s);
    137     n=strlen(s);
    138     for(int i=0;i<n;i++)add(s[i]-'A');
    139     while(m--){
    140         scanf("%s",opt);
    141         gets(mask);
    142         if(opt[0]=='A')for(int i=0;i<n;i++)add(s[i]-'A');
    143         else dfs(1,0);
    144     }
    145     return 0;
    146 }
    View Code
  • 相关阅读:
    创建对象_原型(Prototype)模式_深拷贝
    创建对象_工厂方法(Factory Method)模式 与 静态工厂方法
    创建对象——单例(Singleton)模式
    模板方法模式
    移除HTML5 input在type="number"时的上下小箭头
    颜色名列表
    什么是盒模型?
    JQuery中$.ajax()方法参数详解
    zsh下docker命令tab补全方法
    ubuntu14.04 搭建gitlab服务
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/8377047.html
Copyright © 2020-2023  润新知