Live2d Test Env

HihoCoder1415后缀数组三·重复旋律3

重复旋律3

时间限制:5000ms
单点时限:1000ms
内存限制:256MB

描述

小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一个音乐旋律被表示为长度为 N 的数构成的数列。小Hi在练习过很多曲子以后发现很多作品中的旋律有共同的部分。

旋律是一段连续的数列,如果同一段旋律在作品A和作品B中同时出现过,这段旋律就是A和B共同的部分,比如在abab 在 bababab 和 cabacababc 中都出现过。小Hi想知道两部作品的共同旋律最长是多少?

输入

共两行。一行一个仅包含小写字母的字符串。字符串长度不超过 100000。

输出

一行一个整数,表示答案。

样例输入
abcdefg
abacabca
样例输出
3

 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=210000;
int Rank[maxn],cntA[maxn],cntB[maxn],A[maxn],B[maxn];
int sa[maxn],tsa[maxn],ht[maxn];
int ans,N,ch[maxn];
char str1[maxn],str2[maxn];  
void solve()
{
    int i,j;
    for(i=1;i<=N;i++)  cntA[i]=0;
    for(i=1;i<=N;i++)  cntA[ch[i]]++;
    for(i=1;i<=N;i++)  cntA[i]+=cntA[i-1];
    for(i=N;i>=1;i--)  sa[cntA[ch[i]]--]=i;
    Rank[sa[1]]=1;
    for(i=2;i<=N;i++)  
    {
        Rank[sa[i]]=Rank[sa[i-1]];
        if(ch[sa[i]]!=ch[sa[i-1]]) Rank[sa[i]]++;
    }
    for(int L=1;Rank[sa[N]]<N;L<<=1)
    {
        for(i=0;i<=N;i++) cntA[i]=cntB[i]=0;
        for(i=1;i<=N;i++) cntA[A[i]=Rank[i]]++;
        for(i=1;i<=N;i++) cntB[B[i]=(i+L<=N)?Rank[i+L]:0]++;
        for(i=1;i<=N;i++) cntA[i]+=cntA[i-1];
        for(i=1;i<=N;i++) cntB[i]+=cntB[i-1];
        for(i=N;i>=1;i--) tsa[cntB[B[i]]--]=i;
        for(i=N;i>=1;i--) sa[cntA[A[tsa[i]]]--]=tsa[i];
        Rank[sa[1]]=1;
        for(i=2;i<=N;i++)
        {
            Rank[sa[i]]=Rank[sa[i-1]];
            if(A[sa[i]]!=A[sa[i-1]]||B[sa[i]]!=B[sa[i-1]]) Rank[sa[i]]++;
        }
    }
    for (i=1,j=0;i<=N;i++)
    {
        if(j) j --;
        while (ch[i+j]==ch[sa[Rank[i]-1]+j]) j++;
        ht[Rank[i]]=j;
    }
}
int main()
{
    scanf("%s",str1+1);
    scanf("%s",str2+1);
    int L1=strlen(str1+1);
    int L2=strlen(str2+1);
    for(int i=1;i<=L1;i++) ch[i]=str1[i]-96;
    ch[L1+1]=30;
    for(int i=1;i<=L2;i++) ch[i+L1+1]=str2[i]-96;
    N=L1+L2+1; 
    solve();
    for(int i = 1; i <= N; i++)
    {
        if((sa[i]<=L1)!=(sa[i-1]<=L1))
            ans = max(ans, ht[i]);
    }
    printf("%d\n",ans);
    return 0;
}

 

没有找到原因,开始用字符串一直错,改成数组就AC了。也不知道为什么。过几天再看看吧。

 

posted @ 2017-11-19 18:58  nimphy  阅读(190)  评论(0编辑  收藏  举报