zoukankan      html  css  js  c++  java
  • POJ2774

    Portal

    Description

    求两个字符串(s_1,s_2(|s_1|,|s_2|leq10^5))的最长公共子串。

    Solution

    复习一波后缀数组。
    将两个串连接成s1+'#'+s2,求后缀数组。若(sa[i])(sa[i-1])不在同一串中,用(h[i])更新答案。

    时间复杂度(O(|s|log|s|))

    Code

    //Long Long Message
    #include <cstdio>
    #include <cstring>
    int max(int x,int y) {return x>y?x:y;}
    int const N=2e5+10;
    int n; char s[N];
    int sa[N],rank[N<<1],h[N];
    int cnt[N],tmp[N],rank1[N];
    int main()
    {
        scanf("%s",s+1); n=strlen(s+1);
        int L1=n; s[++n]='#';
        scanf("%s",s+n+1); n=strlen(s+1);
        for(int i=1;i<=n;i++) cnt[s[i]]=1;
        for(int i=1;i<=256;i++) cnt[i]+=cnt[i-1];
        for(int i=1;i<=n;i++) rank[i]=cnt[s[i]];
        for(int L=1;L<=n;L<<=1)
        {
            memset(cnt,0,sizeof cnt);
            for(int i=1;i<=n;i++) cnt[rank[i+L]]++;
            for(int i=1;i<=n;i++) cnt[i]+=cnt[i-1];
            for(int i=n;i>=1;i--) tmp[cnt[rank[i+L]]--]=i;
            memset(cnt,0,sizeof cnt);
            for(int i=1;i<=n;i++) cnt[rank[tmp[i]]]++;
            for(int i=1;i<=n;i++) cnt[i]+=cnt[i-1];
            for(int i=n;i>=1;i--) sa[cnt[rank[tmp[i]]]--]=tmp[i];
            int k=0;
            for(int i=1;i<=n;i++)
            {
                if(rank[sa[i]]!=rank[sa[i-1]]||rank[sa[i]+L]!=rank[sa[i-1]+L]) k++;
                rank1[sa[i]]=k;
            }
            memcpy(rank,rank1,sizeof rank1);
            if(k>=n) break;
        }
        for(int i=1,k=0;i<=n;i++)
        {
            if(rank[i]==1) {h[1]=k=0; continue;}
            if(k) k--;
            while(s[i+k]==s[sa[rank[i]-1]+k]) k++;
            h[rank[i]]=k;
        }
        int ans=0;
        for(int i=1;i<=n;i++) if((sa[i]>L1)^(sa[i-1]>L1)) ans=max(ans,h[i]);
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    hdoj1587
    欧拉定理及其应用
    hdoj1571
    hdoj1050
    POJ推荐50题
    poj2593
    hdoj1286
    hdoj1215七夕节
    我的Linux软件
    ACM题目推荐--《算法艺术与信息学竞赛》(转)
  • 原文地址:https://www.cnblogs.com/VisJiao/p/POJ2774.html
Copyright © 2011-2022 走看看