zoukankan      html  css  js  c++  java
  • bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 后缀数组

    后缀数组求至少重复k次的最长字符串,二分分组即可

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int n,m,p[300010],height[300010],sa[300010],str[300010],cnt[1000010],rank[300010],temp[300010];
    void init()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
        scanf("%d",&str[i]);
    }
    inline bool epu(int x,int y,int l){return rank[x]==rank[y]&&rank[x+l]==rank[y+l];}
    void doubling()
    {
        for(int i=0;i<=n;i++)sa[i]=i,rank[i]=str[i];
        for(int i,l=0,pos=0,sig=1000010;pos<n-1;sig=pos)
        {
            for(i=n-l,pos=0;i<n;i++)p[pos++]=i;
            for(i=0;i<n;i++)if(sa[i]>=l)p[pos++]=sa[i]-l;
            memset(cnt,0,sizeof(cnt));
            for(i=0;i<n;i++)cnt[rank[i]]++;
            for(i=1;i<=sig;i++)cnt[i]+=cnt[i-1];
            for(i=n-1;i>=0;i--)sa[--cnt[rank[p[i]]]]=p[i];
            for(temp[sa[0]]=pos=0,i=1;i<n;i++)
            {
                if(!epu(sa[i],sa[i-1],l))pos++;
                temp[sa[i]]=pos;
            }
            for(i=0;i<n;i++)rank[i]=temp[i];
            if(l==0)str[n]=rank[n]=-1;
            if(!l)l=1;else l<<=1;
        }
         
    }
    void pre()
    {
        int i,k;
        for(i=k=0;i<n;i++)
        {
            if(k)k--;
            if(rank[i]==0)continue;
            for(int j=sa[rank[i]-1];str[i+k]==str[j+k];)
                k++;
            height[rank[i]]=k;
        }
    }
    bool pd(int pp)
    {
        int ans=1;
        for(int i=1;i<n;i++)
        {
            if(height[i]<pp)ans=1;
            else ans++;
            if(ans>=m)return true;
        }
        return false;
    }
    void work()
    {
        int l=0,r=n,mid;
        while(l+1<r)
        {
            mid=(l+r)>>1;
            if(pd(mid))l=mid;
            else r=mid;
        }
        if(pd(r))printf("%d
    ",r);
        else printf("%d
    ",l);
    }
    int main()
    {
        //freopen("xf.in","r",stdin);
        scanf("%d%d",&n,&m);
        memset(str,0,sizeof(str));
        memset(height,0,sizeof(height));
        memset(cnt,0,sizeof(cnt));
        memset(rank,0,sizeof(rank));
        memset(temp,0,sizeof(temp));
        memset(p,0,sizeof(p));
        memset(sa,0,sizeof(sa));
        for(int i=0;i<n;i++)
        scanf("%d",&str[i]);
        doubling();
        pre();
        work();
        return 0;
    }
    

      

  • 相关阅读:
    iOS- static extern const
    App 性能分析
    迭代器和生成器
    软件工程之个人软件开发----起步
    myeclipse调式与属性显示
    hdu 6188
    uva10780 质因子分解
    云服务器端口号的几个操作
    Redis错误 : MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk.
    ubuntu系统安装宝塔面板Linux版
  • 原文地址:https://www.cnblogs.com/mybing/p/8528993.html
Copyright © 2011-2022 走看看