zoukankan      html  css  js  c++  java
  • 【POJ-2774】Long Long Message 后缀数组 最长公共子串(出现两次不重叠子串)

    Long Long Message

    题意

    给出两个字符串,让找出最长的公共子串

    思路

    把两个字符串合起来,做最长不重叠子串即可。

    [poj 1743] Musical Theme 后缀数组 or hash

    数组开二倍

    代码

    /*Gts2m ranks first in the world*/
    #define pb push_back
    #define stop system("pause")
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<stack>
    #include<math.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<bitset>
    #include<string>
    #include<algorithm>
    #include<iostream>
    // #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+10;
    typedef long long ll;
    typedef unsigned long long ull;
    
    char s[N],t[N];
    int sa[N],rk[N],oldrk[N],cnt[N],pos[N],ht[N];
    int n,m;
    bool cmp(int a,int b,int k)
    {
        return oldrk[a]==oldrk[b]&&oldrk[a+k]==oldrk[b+k];
    }
    void getsa()
    {
        m=122;
        memset(cnt,0,sizeof(cnt));
        for(int i=1;i<=n;i++) ++cnt[rk[i]=s[i]];
        for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
        for(int i=n;i;i--) sa[cnt[rk[i]]--]=i;
        // rk[n+1]=0;
        for(int k=1;k<=n;k<<=1)
        {
            int num=0;
            for(int i=n-k+1;i<=n;i++) pos[++num]=i;
            for(int i=1;i<=n;i++) if(sa[i]>k) pos[++num]=sa[i]-k;
            memset(cnt,0,sizeof(cnt));
            for(int i=1;i<=n;i++) ++cnt[rk[i]];
            for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
            for(int i=n;i;i--) sa[cnt[rk[pos[i]]]--]=pos[i];
            num=0;
            memcpy(oldrk,rk,sizeof(rk));
            for(int i=1;i<=n;i++) rk[sa[i]]=cmp(sa[i],sa[i-1],k)?num:++num;
            if(num==n) break;
            m=num;
        }
        for(int i=1;i<=n;i++) rk[sa[i]]=i;
        int k=0;
        for(int i=1;i<=n;i++)
        {
            if(k) --k;
            while(s[i+k]==s[sa[rk[i]-1]+k]) ++k;
            ht[rk[i]]=k;
        }
    }
    int lens,lent;
    int judge(int x)
    {
        int minn=sa[1],maxn=sa[1];
        for(int i=2;i<=n;i++)
        {
            if(ht[i]>=x)
            {
                minn=min(minn,sa[i]);
                maxn=max(maxn,sa[i]);
            }
            else minn=maxn=sa[i];
            if(minn+x-1<=lens&&maxn>lens+1) return 1;
        }
        return 0;
    }
    int main()
    {
        scanf("%s%s",s+1,t+1);
        lens=strlen(s+1),lent=strlen(t+1);
        n=lens;
        s[++n]=0;
        for(int i=1;i<=lent;i++) s[++n]=t[i];
        getsa();
        int l=1,r=min(lens,lent),ans=0;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(judge(mid))
            {
                ans=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        printf("%d
    ",ans);
        // stop;
        return 0;
    }
    
  • 相关阅读:
    原子变量AtomicInteger
    8.2.2.2 Speed of UPDATE Statements 加速UPDATE语句:
    8.2.2 Optimizing DML Statements 优化DML 语句:
    CSS3中-moz、-ms、-webkit和-o分别代表什么意思
    8.2.1.19 Optimizing LIMIT Queries 优化LIMIT 查询:
    java.lang.IllegalArgumentException: Negative time
    8.2.1.17 DISTINCT Optimization
    Python基本语法_函数_参数的多类型传值
    Python基本语法_函数_参数的多类型传值
    8.2.1.16 GROUP BY Optimization
  • 原文地址:https://www.cnblogs.com/valk3/p/12885053.html
Copyright © 2011-2022 走看看