zoukankan      html  css  js  c++  java
  • 【BZOJ2555】SubString(后缀自动机,LCT)

    题意:给你一个字符串init,要求你支持两个操作

    (1):在当前字符串的后面插入一个字符串

    (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)

    你必须在线支持这些操作。

    长度 <= 600000,询问次数<= 10000,询问总长度<= 3000000

    思路:因为有加边,删边,加点操作,需要动态维护SAM中每个right集合的大小,所以使用LCT维护

    需要维护根节点=1号点到每个结点路径上的和,因为固定了1号点为根节点所以不需要makeroot和rev标记

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef unsigned int uint;
      5 typedef unsigned long long ull;
      6 typedef pair<int,int> PII;
      7 typedef pair<ll,ll> Pll;
      8 typedef vector<int> VI;
      9 typedef vector<PII> VII;
     10 typedef pair<ll,int>P;
     11 #define N  1200010
     12 #define M  210000
     13 #define fi first
     14 #define se second
     15 #define MP make_pair
     16 #define pi acos(-1)
     17 #define mem(a,b) memset(a,b,sizeof(a))
     18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
     19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
     20 #define lowbit(x) x&(-x)
     21 #define Rand (rand()*(1<<16)+rand())
     22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
     23 #define ls p<<1
     24 #define rs p<<1|1
     25 
     26 const int MOD=1e9+7,inv2=(MOD+1)/2;
     27       double eps=1e-6;
     28       int INF=1<<29;
     29       ll inf=5e13;
     30       int dx[4]={-1,1,0,0};
     31       int dy[4]={0,0,-1,1};
     32 
     33 
     34 int mask;
     35 char s[3000010];
     36 string chars;
     37 
     38 int read()
     39 {
     40    int v=0,f=1;
     41    char c=getchar();
     42    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     43    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     44    return v*f;
     45 }
     46 
     47 void gets(int mask)
     48 {
     49     scanf("%s",s);
     50     chars=s;
     51     for(int j=0;j<chars.length();j++)
     52     {
     53         mask=(mask*131+j)%chars.length();
     54         char t=chars[j];
     55         chars[j]=chars[mask];
     56         chars[mask]=t;
     57     }
     58 }
     59 
     60 struct lct
     61 {
     62     int t[N][2],w[N],fa[N],q[N],rev[N],tag[N],top;
     63 
     64     void add(int x,int y)
     65     {
     66         if(x)
     67         {
     68             w[x]+=y;
     69             tag[x]+=y;
     70         }
     71     }
     72 
     73     int isroot(int x)
     74     {
     75         return ((t[fa[x]][0]!=x)&&(t[fa[x]][1]!=x));
     76     }
     77 
     78     void pushdown(int x)
     79     {
     80         int l=t[x][0],r=t[x][1];
     81         if(tag[x])
     82         {
     83             add(l,tag[x]);
     84             add(r,tag[x]);
     85             tag[x]=0;
     86         }
     87     }
     88 
     89     void rotate(int x)
     90     {
     91         int y=fa[x],z=fa[y];
     92         int l=(t[y][1]==x),r=l^1;
     93         if(!isroot(y)) t[z][t[z][1]==y]=x;
     94         fa[t[x][r]]=y,fa[y]=x,fa[x]=z;
     95         t[y][l]=t[x][r],t[x][r]=y;
     96     }
     97 
     98     void splay(int x)
     99     {
    100         top=0;
    101         q[++top]=x;
    102         for(int i=x;!isroot(i);i=fa[i]) q[++top]=fa[i];
    103         while(top) pushdown(q[top--]);
    104         while(!isroot(x))
    105         {
    106             int y=fa[x],z=fa[y];
    107             if(!isroot(y))
    108             {
    109                 if((t[y][0]==x)^(t[z][0]==y)) rotate(x);
    110                  else rotate(y);
    111             }
    112             rotate(x);
    113         }
    114     }
    115 
    116     void access(int x)
    117     {
    118         for(int k=0;x;k=x,x=fa[x])
    119         {
    120             splay(x);
    121             t[x][1]=k;
    122         }
    123     }
    124 
    125     void link(int x,int y)
    126     {
    127         fa[x]=y;
    128         access(y);
    129         splay(y);
    130         add(y,w[x]);
    131     }
    132 
    133     void cut(int x)
    134     {
    135         access(x);
    136         splay(x);
    137         add(t[x][0],-w[x]);
    138         fa[t[x][0]]=0;
    139         t[x][0]=0;
    140     }
    141 
    142 }lct;
    143 
    144 struct sam
    145 {
    146     int cnt;
    147     int F[N],ch[N][26];
    148     int st[N],b[N],bl[N],c[N];
    149     int p,np,q,nq;
    150 
    151     sam()
    152     {
    153         cnt=np=1;
    154     }
    155 
    156     void extend(int x)
    157     {
    158         p=np; st[np=++cnt]=st[p]+1;
    159         while(p&&!ch[p][x])
    160         {
    161             ch[p][x]=np;
    162             p=F[p];
    163         }
    164         lct.w[np]=1;
    165         if(!p) F[np]=1,lct.link(np,1);
    166          else if(st[p]+1==st[q=ch[p][x]]) F[np]=q,lct.link(np,q);
    167           else
    168           {
    169               st[nq=++cnt]=st[p]+1;
    170               memcpy(ch[nq],ch[q],sizeof ch[q]);
    171               F[nq]=F[q];
    172               lct.link(nq,F[q]);
    173               F[np]=F[q]=nq;
    174               lct.cut(q);
    175               lct.link(q,nq);
    176               lct.link(np,nq);
    177               while(ch[p][x]==q)
    178               {
    179                     ch[p][x]=nq;
    180                     p=F[p];
    181               }
    182           }
    183     }
    184 
    185     void build()
    186     {
    187         scanf("%s",s);
    188         int n=strlen(s);
    189         rep(i,0,n-1) extend(s[i]-'A');
    190     }
    191 
    192     void add()
    193     {
    194         gets(mask);
    195         int n=chars.length();
    196         rep(i,0,n-1) extend(chars[i]-'A');
    197     }
    198 
    199     int query()
    200     {
    201         gets(mask);
    202         int p=1,n=chars.length();
    203         rep(i,0,n-1)
    204         {
    205             p=ch[p][chars[i]-'A'];
    206             if(!p) return 0;
    207         }
    208         lct.splay(p);
    209         return lct.w[p];
    210     }
    211 
    212 }sam;
    213 
    214 
    215 int main()
    216 {
    217     int Q;
    218     scanf("%d",&Q);
    219     sam.build();
    220     while(Q--)
    221     {
    222         scanf("%s",s);
    223         if(s[0]=='A') sam.add();
    224          else
    225          {
    226             int ans=sam.query();
    227             printf("%d
    ",ans);
    228             mask^=ans;
    229          }
    230     }
    231     return 0;
    232 }
    233 
  • 相关阅读:
    GIT学习笔记(2):时光机穿梭与远程仓库
    CNN学习笔记:正则化缓解过拟合
    Java分布式:RPC(远程过程调用)
    设计模式:学习笔记(12)——代理模式
    算法:乐观锁与悲观锁
    Python:笔记(5)——错误、调试和测试
    算法:LRU(最近最少使用)
    Python:笔记(4)——高级特性
    方法论:带着问题找答案
    Cache-Aside模式
  • 原文地址:https://www.cnblogs.com/myx12345/p/11514878.html
Copyright © 2011-2022 走看看