zoukankan      html  css  js  c++  java
  • poj1743 Musical Theme

    题目描述:给出长度为n的数字串,求两个串,满足:

    1.长度相等且大于5;

    2.对应项差值相同;

    代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 40050
    int n,a[N],b[N];
    int rank[N],tr[N],hs[N],sa[N],h[N];
    bool cmp(int aa,int ab,int k)
    {
        if(aa+k>n||ab+k>n)return 0;
        return rank[aa]==rank[ab]&&rank[aa+k]==rank[ab+k];
    }
    void init()
    {
        for(int i=1;i<=n;i++)
            hs[i]=tr[i]=rank[i]=sa[i]=h[i]=0;
    }
    void get_sa()
    {
        int i,cnt=0;
        for(i=1;i<=n;i++)hs[b[i]]++;
        for(i=1;i<=200;i++)if(hs[i])tr[i]=++cnt;
        for(i=1;i<=200;i++)hs[i]+=hs[i-1];
        for(i=n;i>=1;i--)rank[i]=tr[b[i]],sa[hs[b[i]]--]=i;
        for(int k=1;cnt!=n;k<<=1)
        {
            for(i=1;i<=n;i++)hs[i]=0;
            for(i=1;i<=n;i++)hs[rank[i]]++;
            for(i=1;i<=n;i++)hs[i]+=hs[i-1];
            for(i=n;i>=1;i--)if(sa[i]>k)tr[sa[i]-k]=hs[rank[sa[i]-k]]--;
            for(i=1;i<=k;i++)tr[n-i+1]=hs[rank[n-i+1]]--;
            for(i=1;i<=n;i++)sa[tr[i]]=i;
            for(i=1,cnt=0;i<=n;i++)tr[sa[i]]=cmp(sa[i-1],sa[i],k)?cnt:++cnt;
            for(i=1;i<=n;i++)rank[i]=tr[i];
        }
    }
    void get_h()
    {
        for(int i=1;i<=n;i++)
        {
            if(rank[i]==1)continue;
            for(int j=max(h[rank[i-1]]-1,1);;j++)
            {
                if(b[i+j-1]==b[sa[rank[i]-1]+j-1])h[rank[i]]=j;
                else break;
            }
        }
    }
    bool check(int len)
    {
        for(int i=2;i<=n;i++)
        {
            if(h[i]<len)continue;
            for(int j=i-1;j>=2;j--)
            {
                if(abs(sa[i]-sa[j])>=len)return 1;
                if(h[j]<len)break;
            }
        }
        return 0;
    }
    int main()
    {
        while(scanf("%d",&n))
        {
            if(!n)break;
            init();
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            if(n<10)
            {
                printf("0
    ");
                continue;
            }
            n--;
            for(int i=1;i<=n;i++)
                b[i]=a[i+1]-a[i]+100;
            get_sa();
            get_h();
            int l = 0,r = n+1,ans;
            while(l<=r)
            {
                int mid =(l+r)>>1;
                if(check(mid))
                {
                    ans = mid;
                    l=mid+1;
                }else r=mid-1;
            }
            if(ans<4)printf("0
    ");
            else printf("%d
    ",ans+1);
        }
        return 0;
    }
  • 相关阅读:
    无重复字符的最长子串
    最长公共前缀
    项目开发的 工程化
    包管理 import debug 模块管理 module
    Third Party Browser Drivers NOT DEVELOPED by seleniumhq
    任何不看源码的代码引入都是存在定时爆炸的可能
    博客数计数
    lineage 世系 血缘 容错机制 DAG
    查源码分析 游标 写 需要 cursors 一切不看源码的代码引入都是定时炸弹的启动
    8核 16g 及时释放内存空间
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9699204.html
Copyright © 2011-2022 走看看