zoukankan      html  css  js  c++  java
  • SAM维护的在线LCS

    题目大意:

    给定两个字符串,存在三种操作,分别是在a,b串末尾加一个字符串,和询问两串的LCS

    题解:

    Get新套路:把两串建在同一SAM上,将重合的位置合并为同一节点,再加个标记数组,如果两者的LCS标记都存在那么就直接更新答案.

    注意标记需要沿father上传,每新建一个节点就打上标记并更新祖先

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #define RG register
     8 using namespace std;
     9 const int N=5000005,M=10000005;
    10 char S[N];int ch[M][3],fa[M],cur=1,cnt=1,ans=0,n=0,s[2][N],m=0,dis[M],pre[2][N],l[N];
    11 int mark[M];long long ret=0;
    12 void updata(int p){
    13     while(fa[p] && (mark[p]&mark[fa[p]])!=mark[p]){
    14         if(mark[p]==3)ans=max(ans,dis[p]);
    15         mark[fa[p]]|=mark[p];
    16         p=fa[p];
    17     }
    18     if(mark[p]==3)ans=max(ans,dis[p]);
    19 }
    20 int build(int last,int k,int c)
    21 {
    22    cur=++cnt;dis[cur]=dis[last]+1;
    23     RG int p=last;
    24     for(;p && !ch[p][c];p=fa[p])ch[p][c]=cur;
    25     if(!p)fa[cur]=1;
    26     else{
    27         int q=ch[p][c];
    28         if(dis[q]==dis[p]+1)fa[cur]=q;
    29         else{
    30             int nt=++cnt;dis[nt]=dis[p]+1;
    31             memcpy(ch[nt],ch[q],sizeof(ch[q]));
    32             fa[nt]=fa[q];fa[q]=fa[cur]=nt;
    33             updata(q);                          /*不能忘记这个地方*/
    34             for(;ch[p][c]==q;p=fa[p])ch[p][c]=nt;
    35         }
    36     }
    37     mark[cur]|=(1<<k);
    38     updata(cur);
    39     return cur;
    40 }
    41 void work()
    42 {
    43     int Q,fg0,fg1;
    44     scanf("%d",&Q);scanf("%s",S+1);
    45     pre[0][0]=pre[1][0]=1;
    46     for(int i=1,x;i<=Q;i++){
    47         x=S[i]-'0';
    48         fg0=(x^ans)%2;fg1=((x^ans)>>1)%2;fg1++;
    49         s[fg0][++l[fg0]]=fg1;
    50         if(pre[fg0][l[fg0]-1]==pre[fg0^1][l[fg0]-1] && fg1==s[fg0^1][l[fg0]]){
    51             pre[fg0][l[fg0]]=pre[fg0^1][l[fg0]];
    52             mark[pre[fg0][l[fg0]]]|=(1<<fg0);
    53             updata(pre[fg0][l[fg0]]);
    54         }
    55         else{
    56             pre[fg0][l[fg0]]=build(pre[fg0][l[fg0]-1],fg0,fg1);
    57         }
    58         ret+=ans;
    59     }
    60     printf("%lld
    ",ret);
    61 }
    62 int main()
    63 {
    64     freopen("lcs.in","r",stdin);
    65     freopen("lcs.out","w",stdout);
    66     work();
    67     return 0;
    68 }
  • 相关阅读:
    python学习day02
    鼓起勇气 大胆说不
    spring系列---- spring-mvc1
    win7-64位 jdk安装
    项目分层以及阶段期限规划
    老油条之记
    论软件与管理的关系---企业管理软件的末路
    软件项目管理之觞
    世界在变化-----谷歌不安全
    LPR利率与固定利率哪个更合算?
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7287183.html
Copyright © 2011-2022 走看看