zoukankan      html  css  js  c++  java
  • poj2774

    思路

    求出height之后
    只要相邻两个子串是本串不同的来更新就好
    因为这样一定是最优啊、、取min显然越长越不好

    (这里'%'当成‘{’吧)
    abc%bca
    height  i          sa  belong
    0       1 a        7   2
    1       2 abc@bca  1   1
    0       3 bca      5   2
    2       4 bc@bca   2   1
    0       5 ca       6   2
    1       6 c@bca    3   1
    0       7 @bca     4   2
    

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define FOR(i,a,b) for(int i=a;i<=b;++i)
    #define ROF(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    const int maxn=4e5+7;
    const int inf=0x3f3f3f3f;
    char s[maxn],a[maxn];
    int n,m,x[maxn],c[maxn],rk[maxn],sa[maxn];
    int read() {
        int x=0,f=1;char s=getchar();
        for(;s<'0'||s>'9';s=getchar()) if(s=='-') f=-1;
        for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
        return x*f;
    }
    void get_sa() {
        FOR(i,1,n) ++c[rk[i]=s[i]];
        FOR(i,2,m) c[i]+=c[i-1];
        ROF(i,n,1) sa[c[rk[i]]--]=i;
        for(int k=1;k<=n;k<<=1) {
            int p=0;
            FOR(i,n-k+1,n) x[++p]=i;
            FOR(i,1,n) if(sa[i]>k) x[++p]=sa[i]-k;
            FOR(i,1,m) c[i]=0;
            FOR(i,1,n) ++c[rk[i]];
            FOR(i,2,m) c[i]+=c[i-1];
            ROF(i,n,1) sa[c[rk[x[i]]]--]=x[i],x[i]=0;
            swap(rk,x);
            rk[sa[1]]=1,p=1;
            FOR(i,2,n)
                rk[sa[i]]=(x[sa[i]]==x[sa[i-1]]&&x[sa[i]+k]==x[sa[i-1]+k]) ? p : ++p;
            if(p==n) break;
            m=p;
        }
    }
    int height[maxn];
    void get_height() {
        FOR(i,1,n) rk[sa[i]]=i;
        int k=0;
        FOR(i,1,n) {
            k=k?k-1:0;
            int j=sa[rk[i]-1];
            while(s[i+k]==s[j+k]&&i+k<=n&&j+k<=n)k++;
            height[rk[i]]=k;
        }
    }
    int main() {
        scanf("%s",s+1);
        int gg;
        gg=n=strlen(s+1);
        m=250;
        s[++n]='z'+1;//感觉加不加间隔符没啥关系,去掉也能A
        scanf("%s",a+1);
        int lb=strlen(a+1);
        FOR(i,1,lb) s[++n]=a[i];
        get_sa();
        get_height();
        int ans=0;
        FOR(i,1,n) {
            if(sa[i]>gg && sa[i-1]<gg) ans=max(ans,height[i]);
            if(sa[i]<gg && sa[i-1]>gg) ans=max(ans,height[i]);
        }
        cout<<ans<<"
    ";
        return 0;
    }
    
  • 相关阅读:
    LeetCode(122. 买卖股票的最佳时机 II)
    LeetCode(485. 最大连续1的个数)

    约瑟夫问题
    链表
    队列
    稀疏数组
    乐优商城项目学习
    LeetCode_Climbing Stairs
    数据结构&&算法基础知识
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10153624.html
Copyright © 2011-2022 走看看