首页 > 代码库 > 【bzoj】1717 [Usaco2006 Dec]Milk Patterns 产奶的模式
【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; }
【bzoj】1717 [Usaco2006 Dec]Milk Patterns 产奶的模式
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。