【BZOJ1717】产奶的模式 后缀数组

来源:互联网 发布:网狐数据库配置生成器 编辑:程序博客网 时间:2024/04/30 13:26

无脑后缀数组大法好QAQ

还是在height数组上做文章,等价于找序列中【连续K-1个height值中的最小值】的最大值,滑动窗口维护更新即可。

第一次发现pair如此好♂用

/**************************************************************    Problem: 1717    User: cqyzhb    Language: C++    Result: Accepted    Time:20 ms    Memory:2564 kb****************************************************************/ #include<cstdlib>#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#include<vector>using namespace std;#define MAXN 40005void _read(int &x){    x=0; char ch=getchar(); bool flag=false;    while(ch<'0' || ch>'9'){if(ch=='-')flag=true; ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} if(flag)x=-x; return ;}int N,K,A[MAXN],M,B[MAXN];char s[MAXN];void Init(){    _read(N); _read(K); K--;    for(int i=1;i<=N;_read(A[i]),B[i]=A[i],i++);    sort(B+1,B+1+N);    M=unique(B+1,B+1+N)-B-1;    for(int i=1;i<=N;i++)A[i]=lower_bound(B+1,B+1+M,A[i])-B;    return ;}int wa[MAXN],wb[MAXN],wc[MAXN],sa[MAXN],h[MAXN],rank[MAXN];void make_sa(){    int *t,*x=wa,*y=wb,i,k,cnt;    for(i=0;i<=M;i++)wc[i]=0;    for(i=1;i<=N;i++)wc[x[i]=A[i]]++;    for(i=1;i<=M;i++)wc[i]+=wc[i-1];    for(i=N;i>=1;i--)sa[wc[x[i]]--]=i;    for(k=1;k<=N;k=k*2)    {        cnt=0;        for(i=N-k+1;i<=N;i++)y[++cnt]=i;        for(i=1;i<=N;i++)if(sa[i]>k)y[++cnt]=sa[i]-k;        for(i=0;i<=M;i++)wc[i]=0;        for(i=1;i<=N;i++)wc[x[y[i]]]++;        for(i=1;i<=M;i++)wc[i]+=wc[i-1];        for(i=N;i>=1;i--)sa[wc[x[y[i]]]--]=y[i];        for(t=x,x=y,y=t,cnt=1,x[sa[1]]=1,i=2;i<=N;i++)        x[sa[i]]= (y[sa[i-1]]==y[sa[i]])&&(y[sa[i-1]+k]==y[sa[i]+k]) ? cnt : ++cnt ;        M=cnt; if(cnt==N)break;    }    for(i=1;i<=N;i++)rank[sa[i]]=i;    k=0;    for(int i=1;i<=N;h[rank[i]]=k,i++)    {        if(k)k--;for(int j=sa[rank[i]-1];A[i+k]==A[j+k];k++);    }    return ;}priority_queue<pair<int,int>,vector<pair<int,int> > >pq;int main(){//  freopen("in.txt","r",stdin);    Init();    make_sa();    int ans=0;    for(int i=1;i<K;i++)pq.push(make_pair(-h[i],i));    for(int i=K;i<=N;i++)    {        pq.push(make_pair(-h[i],i));        while(pq.top().second <= i-K)pq.pop();        ans=max(ans,-pq.top().first );    }    printf("%d\n",ans);    return 0;}


0 0
原创粉丝点击