zoukankan      html  css  js  c++  java
  • 【bzoj】1717 [Usaco2006 Dec]Milk Patterns 产奶的模式

    【算法】后缀数组

    【题解】后缀数组

    由于m太大,先离散化。

    然后处理SA和LCP。

    最后用单调队列处理即可。

    注意实际上队列头尾长度限制是K-1.

    删队尾不要删过头

    i≥K才能开始统计答案。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=20010;
    int n,m,s[maxn],x[maxn],y[maxn],base[maxn],sa[maxn],h[maxn],K,q[maxn];
    struct lshs{int ord,num;}lsh[maxn];
    bool cmp(lshs a,lshs b)
    {return a.num<b.num;}
    void build_sa(int m)
    {
        for(int i=1;i<=m;i++)base[i]=0;
        for(int i=1;i<=n;i++)base[x[i]=s[i]]++;
        for(int i=2;i<=m;i++)base[i]+=base[i-1];
        for(int i=n;i>=1;i--)sa[base[x[i]]--]=i;
        for(int k=1;k<=n;k<<=1)
         {
             int p=0;
             for(int i=n-k+1;i<=n;i++)y[++p]=i;
             for(int i=1;i<=n;i++)if(sa[i]>k)y[++p]=sa[i]-k;
             for(int i=1;i<=m;i++)base[i]=0;
             for(int i=1;i<=n;i++)base[x[i]]++;
             for(int i=2;i<=m;i++)base[i]+=base[i-1];
             for(int i=n;i>=1;i--)sa[base[x[y[i]]]--]=y[i];
             swap(x,y);
             p=1;x[sa[1]]=1;
             for(int i=2;i<=n;i++)
              x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p;
             if(p>=n)break;
             m=p;
         }
        int k=0;
        for(int i=1;i<=n;i++)
         {
             if(k)k--;
             int j=sa[x[i]-1];
             while(s[i+k]==s[j+k])k++;
             h[x[i]]=k;
         }
    }
    int main()
    {
        scanf("%d%d",&n,&K);
        for(int i=1;i<=n;i++)
         {
             scanf("%d",&lsh[i].num);
             lsh[i].ord=i;
         }
        sort(lsh+1,lsh+n+1,cmp);
        int p=1;s[lsh[1].ord]=1;
        for(int i=2;i<=n;i++)s[lsh[i].ord]=lsh[i].num==lsh[i-1].num?p:++p;
        build_sa(p);
        K--;
        int head=0,tail=0;
        int ans=0;
        for(int i=2;i<=n;i++)
         {
             while(h[q[tail-1]]>h[i]&&tail>head)tail--;
             q[tail++]=i;
             if(i-q[head]>=K)head++;
             if(i>=K+1)ans=max(ans,h[q[head]]);
         }
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    IO模型(一)
    协程(效率最快、重点)--初识协程、gevent模块、协程爬虫、协程socket(一)
    servlet工作原理解析
    servlet:servletconfig对象和它在开发过程中的应用场景
    servlet:线程安全问题
    servlet:启动的时机
    servlet:第一个demo
    安装myeclipse的一些配置
    同时安装32和64位的jdk
    fiddler:网络限速
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6662241.html
Copyright © 2011-2022 走看看