题解-P2852 [USACO06DEC]牛奶模式Milk Patterns

SA+单调队列,太简单了就放在这里吧。

#include<iostream>
#include<cstdio>
using namespace std;
const int N=2e4+4;
const int M=1e6+6;

int t1[N],t2[N],c[M];
int sa[N],rk[N],ht[N];
int a[N];

void gtsa(int n,int m){
    int *x=t1,*y=t2;
    int i,j,p=0;
    for(i=1;i<=n;i++)
        ++c[x[i]=a[i]];
    for(i=1;i<=m;i++)
        c[i]+=c[i-1];
    for(i=n;i;i--)
        sa[c[x[i]]--]=i;
    for(j=1;j<=n&&p<n;j<<=1){
        p=0;
        for(i=n-j+1;i<=n;i++)
            y[++p]=i;
        for(i=1;i<=n;i++)
            if(sa[i]>j)
                y[++p]=sa[i]-j;
        for(i=0;i<=m;i++)
            c[i]=0;
        for(i=1;i<=n;i++)
            ++c[x[y[i]]];
        for(i=1;i<=m;i++)
            c[i]+=c[i-1];
        for(i=n;i;i--)
            sa[c[x[y[i]]]--]=y[i];
        swap(x,y);
        p=1;
        x[sa[1]]=1;
        for(i=2;i<=n;i++)
            x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+j]==y[sa[i-1]+j]?p:++p;
        m=p;
    }
    for(i=1;i<=n;i++)
        rk[sa[i]]=i;
    p=0;
    a[n+1]=-1;
    for(i=1;i<=n;i++){
        j=sa[rk[i]-1];
        if(p)--p;
        while(a[i+p]==a[j+p])
            ++p;
        ht[rk[i]]=p;
    }
}

int main()
{
    int n,m,i;
    scanf("%d%d",&n,&m);
    if(m==1){
        printf("%d",n);
        return 0;
    }
    for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
    gtsa(n,M-1);
    int s=1,t=0,ans=0;
    for(i=1;i<m;i++){
        while(t>=s&&ht[c[t]]>ht[i])
            --t;
        c[++t]=i;
    }
    for(i=m;i<=n;i++){
        while(t>=s&&ht[c[t]]>ht[i])
            --t;
        c[++t]=i;
        while(c[s]+m-1<=i)
            ++s;
        ans=max(ans,ht[c[s]]);
    }
    printf("%d",ans);
    return 0;
}

 

上一篇:Microservices Patterns 2018.10


下一篇:《Game Programming Patterns》游戏设计模式