zoukankan      html  css  js  c++  java
  • 后缀数组三·重复旋律3

    #1415 : 后缀数组三·重复旋律3

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

    描述

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

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

    解题方法提示

    输入

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

    输出

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

    样例输入
    abcdefg
    abacabca
    样例输出
    3
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<cmath>
    #include <bits/stdc++.h>
    #include<vector>
    typedef long long ll;
    const int maxn=2e6+6;
    using namespace std;
    typedef std::pair<ll,ll> pll;
    typedef std::string str;
    int sa[maxn],rk[maxn],tp[maxn],height[maxn];
    char s1[maxn],s2[maxn];
    int ton[maxn],e[maxn],mx,n;
    inline void rsort(){
        for(register int i=0;i<mx;++i)ton[i]=0;
        for(register int i=1;i<=n;++i)ton[rk[i]]++;
        for(register int i=1;i<=mx;++i)ton[i]=ton[i]+ton[i-1];
        for(register int i=n;i>=1;--i)sa[ton[rk[tp[i]]]--]=tp[i];
    }
    inline void solve(){
        for(register int i=1;i<=n;++i)rk[i]=e[i],tp[i]=i;
        rsort();
        for(register int w=1,p=0;w<=n&&p<n;w*=2,mx=p){
            p=0;
            for(register int i=n-w+1;i<=n;++i){
                tp[++p]=i;
            }
            for(register int i=1;i<=n;++i){
                if(sa[i]>w){
                    tp[++p]=sa[i]-w;
                }
            }
            rsort();
            swap(rk,tp);
            rk[sa[1]]=p=1;
            for(register int i=2;i<=n;++i){
                rk[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+w]==tp[sa[i]+w])?p:++p;
            }
            if(p>=n)break;
        }
        int k=0;
        for(register int i=1;i<=n;++i){
            rk[sa[i]]=i;
        }
        for(register int i=1;i<=n;++i){
            if(k)k--;
            else k=0;
            int j=sa[rk[i]-1];
            while(e[i+k]==e[j+k])++k;
            height[rk[i]]=k;
        }
    }
    int main() {
        //freopen("1.txt","r",stdin);
        scanf("%s%s",s1+1,s2+1);
        int len1=strlen(s1+1),len2=strlen(s2+1);
        n=len1+len2+1;
        for(register int i=1;i<=len1;++i){
            e[i]=s1[i]-'a'+1;
            mx=max(mx,e[i]);
        }
        for(register int i=1;i<=len2;++i){
            e[i+len1+1]=s2[i]-'a'+1;
            mx=max(mx,e[i+len1+1]);
        }
        e[len1+1]=300;
        mx=max(mx,300);
        solve();
        int res=0;
    //    for(register int i=1;i<=n;++i){
    //        printf("debug rk[%d] = %d sa[%d] = %d height[%d] = %d
    ",i,rk[i],i,sa[i],i,height[i]);
    //    }
        for(register int i=2;i<=n;++i){
            if(sa[i]<=len1&&sa[i-1]<=len1)continue;
            if(sa[i]>len1&&sa[i-1]>len1)continue;
            res=max(res,height[i]);
        }
        printf("%d
    ",res);
        return 0;
    }
    /*
     * abcdefg
       abacabca
     */
  • 相关阅读:
    FZU-2087 统计树边(最小生成树)
    HDU-1599 find the mincost route(floyd求最小环)
    BZOJ-1191 [HNOI2006]超级英雄Hero(二分图匹配)
    FZU-2020 组合(Lucas定理)
    FZU-2232 炉石传说(二分图匹配)
    NOIP2016模拟 拼接mf(模拟)
    2016年11月10日00:26:08
    BZOJ2986 Non-Squarefree Numbers
    BZOJ3624 [Apio2008]免费道路
    BZOJ3224 Tyvj 1728 普通平衡树
  • 原文地址:https://www.cnblogs.com/czy-power/p/11406120.html
Copyright © 2011-2022 走看看