zoukankan      html  css  js  c++  java
  • 【POJ1743】—Musical Theme(后缀数组)

    传送门

    大意:给你一个字符串,求长度超过4、出现2次以上的最长串的长度

    首先取相邻的差作为字符串

    对这个串建立后缀数组之后

    我们二分枚举这个最长串的长度

    把所有相邻的htht大于midmid化作一组

    取其中的最大最小值的差

    如果存在一组内的差大于midmid,返回TrueTrue,反之FalseFalse

    代码:

    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<cstdio>
    using namespace std;
    inline int read(){
        char ch=getchar();
        int res=0;
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return res;
    }
    const int N=20005;
    const int inf=100000000;
    int n,m,rk[N],sa[N],a[N],p[N],sa2[N],cnt[N],ht[N];
    inline void bucket_sort(){
        for(int i=1;i<=m;i++)cnt[i]=0;
        for(int i=1;i<=n;i++)++cnt[rk[sa2[i]]];
        for(int i=1;i<=m;i++)cnt[i]+=cnt[i-1];
        for(int i=n;i>0;i--)sa[cnt[rk[sa2[i]]]--]=sa2[i];
    }
    inline void init(){
        for(int i=1;i<=n;i++)rk[i]=a[i],sa2[i]=i;
        bucket_sort();
        for(int i=1,pos=0;i<=n&&pos<n;i<<=1){
            pos=0;
            for(int j=n-i+1;j<=n;j++)sa2[++pos]=j;
            for(int j=1;j<=n;j++)if(sa[j]>i)sa2[++pos]=sa[j]-i;
            bucket_sort();
            swap(rk,sa2);
            rk[sa[1]]=1,pos=1;
            for(int j=2;j<=n;j++)rk[sa[j]]=((sa2[sa[j]]==sa2[sa[j-1]])&&(sa2[sa[j]+i]==sa2[sa[j-1]+i])?pos:++pos);
            m=pos;
        }
        for(int i=1;i<=n;i++)rk[sa[i]]=i;
        for(int i=1,k=0,j;i<=n;ht[rk[i++]]=k){
            for(k?k--:0,j=sa[rk[i]-1];a[i+k]==a[j+k];k++);
        }
    }
    inline bool check(int k){
        int minn=inf,maxn=-inf;
        for(int i=1;i<=n;i++){
            if(ht[i]<k){maxn=-inf,minn=inf;continue;}
            maxn=max(maxn,max(sa[i],sa[i-1])),minn=min(minn,min(sa[i],sa[i-1]));
            if(maxn-minn>k)return true;
        }
        return false;
    }
    int main(){
        n=read();
        while(n){
            for(int i=1;i<=n;i++)p[i]=read();
            --n,m=176;
            for(int i=1;i<=n;i++)a[i]=p[i+1]-p[i]+88;
            init();
            int l=4,r=n,ans=0;
            while(l<=r){
                int mid=(l+r)>>1;
                if(check(mid))l=mid+1,ans=mid;
                else r=mid-1;
            }
            if(!ans)ans=-1;
            ans++;
            cout<<ans<<'
    ';
            n=read();
        }
    }
    
  • 相关阅读:
    ISO9126 软件质量模型
    java 15.String
    java 14. ArrayList常用方法
    java 13. 方法重载构造方法块this用法
    linux ssh连接心跳检查断开连接
    关于递归,我有几句话想说
    pytest 报错 ImportError: cannot import name 'main'
    递归回溯剪枝之斐波那契数列
    appium-doctor诊断信息不完整
    数据驱动,关键字驱动,混合驱动简单模型
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366375.html
Copyright © 2011-2022 走看看