zoukankan      html  css  js  c++  java
  • poj2774 Long Long Message(后缀数组)

    http://poj.org/problem?id=2774

    先做一道小水题提提神

    题意:求两个串的最长公共连续子串

    可以二分+哈希做

    但我要用后缀数组做

    两个串拼起来,然后取满足后缀起点分别属于两个串的height数组的最大值

    一开始没用特殊字符隔开两个串

    他AC了,数据有缺陷呐

    第二个串因为最后面是字符串的结束,可以保证公共串不会越界第二个串

    但第一个串就没保证了,例如 baa和aaa

    然后加了特殊字符'#'隔开,它RE了。。。

    因为后缀数组的时候,统计前缀和是 字符-'a'+1,统计1—26,‘#’不满足要求

    用 'a'+26,统计1——27

    一不留神就出bug,哎

    #include<cmath>
    #include<cstdio>
    #include<cstring> 
    #include<algorithm>
    
    using namespace std;
    
    #define N 200005
    
    char ch[N];
    int m,n,k,a[N],v[N],p,q,sa[2][N],rk[2][N],h[N];
    
    
    void mul(int *sa,int *rk,int *SA,int *RK)
    {
        for(int i=1;i<=n;i++) v[rk[sa[i]]]=i;
        for(int i=n;i;i--)
            if(sa[i]>k) 
                SA[v[rk[sa[i]-k]]--]=sa[i]-k;
        for(int i=n-k+1;i<=n;i++) 
            SA[v[rk[i]]--]=i;
        for(int i=1;i<=n;i++) 
            RK[SA[i]]=RK[SA[i-1]]+(rk[SA[i]]!=rk[SA[i-1]]||rk[SA[i]+k]!=rk[SA[i-1]+k]);
    }
    void presa()
    {
        p=0;
        q=1;
        for(int i=1;i<=27;++i) v[i]=0;
        for(int i=1;i<=n;i++) v[a[i]]++;
        for(int i=1;i<=27;i++) v[i]+=v[i-1];
        for(int i=1;i<=n;i++) 
            sa[p][v[a[i]]--]=i;
        for(int i=1;i<=n;i++) 
            rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i-1]]!=a[sa[p][i]]);
        for(k=1;k<n;k<<=1,swap(p,q))
            mul(sa[p],rk[p],sa[q],rk[q]);
        for(int i=1,k=0;i<=n;i++)
        {
            int j=sa[p][rk[p][i]-1];
            while(a[i+k]==a[j+k]) k++;
            h[rk[p][i]]=k;if(k) k--;
        }
    }
    
    void solve()
    {
        int ans=0,t1,t2;
        for(int i=2;i<=n;++i)
        {
            t1=sa[p][i]<=m;
            t2=sa[p][i-1]<=m;
            if(t1+t2==1) ans=max(ans,h[i]);
        }
        printf("%d",ans);
    }
    
    int main()
    {
        scanf("%s",ch+1);
        m=strlen(ch+1);
        ch[++m]='a'+26;
        scanf("%s",ch+m+1);
        n=strlen(ch+1);
        for(int i=1;i<=n;i++) a[i]=ch[i]-'a'+1;
        presa();
        solve();
    }
    作者:xxy
    本文版权归作者和博客园共有,转载请用链接,请勿原文转载,Thanks♪(・ω・)ノ。
  • 相关阅读:
    p4841 城市规划
    p2619 [国家集训队2]Tree I [wqs二分学习]
    p3723 [AH2017/HNOI2017]礼物
    p5437 【XR-2】约定
    p5349 幂
    数据结构:结构之美
    你所不知道的传输层
    为什么选择这种技术而不选择另一种技术?
    Internet路由-主机路由表和转发表
    计算机网络----数据链路层(三)
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/15142575.html
Copyright © 2011-2022 走看看