[bzoj1717][Usaco2006 Dec]Milk Patterns 產奶的模式_後綴數組_二分答案
阿新 • • 發佈:2018-12-12
觀察 ios 有變 lse 當前 typename 直接 ostream 答案
Milk Patterns 產奶的模式 bzoj-1717 Usaco-2006 Dec
題目大意:給定一個字符串,求最長的至少出現了$k$次的子串長度。
註釋:$1\le n\le 2\cdot 10^4$,$2\le k\le n$。
想法:不難想到二分答案,現在我們考慮如何驗證。
這裏就是後綴數組的一個妙用了。
我們對原串建立後綴數組,觀察$ht$數組。
考慮當前二分出來的$mid$。如果有至少連續$k$的$ht$值都不小於$mid$,那麽$k$就是合法的。
故此我們直接掃$ht$數組看看最長的連續比$mid$大的$ht$有多少個即可。
Code:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define N 1000010 using namespace std; int wv[N],wa[N],sa[N],Ws[N],wb[N],t[N],rk[N],ht[N],r[N]; int n,m=1000009; inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;} int rd() {int x=0; char c=nc(); while(!isdigit(c)) c=nc(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=nc(); return x;} void build_sa() { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) Ws[i]=0; for(i=0;i<n;i++) Ws[x[i]=r[i]]++; for(i=1;i<m;i++) Ws[i]+=Ws[i-1]; for(i=n-1;~i;i--) sa[--Ws[x[i]]]=i; for(p=j=1;p<n;j<<=1,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]-j>=0) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) Ws[i]=0; for(i=0;i<n;i++) Ws[wv[i]]++; for(i=1;i<m;i++) Ws[i]+=Ws[i-1]; for(i=n-1;~i;i--) sa[--Ws[wv[i]]]=y[i]; for(t=x,x=y,y=t,i=p=1,x[sa[0]]=0;i<n;i++) { if(y[sa[i]]==y[sa[i-1]]&&y[sa[i-1]+j]==y[sa[i]+j]) x[sa[i]]=p-1; else x[sa[i]]=p++; } } for(i=1;i<n;i++) rk[sa[i]]=i; for(i=p=0;i<n-1;ht[rk[i++]]=p) for(p?p--:0,j=sa[rk[i]-1];r[i+p]==r[j+p];p++); } template <typename T> void Max(T &x,T y) {x=max(x,y);} // inline void Max(int &x,int y) {x=max(x,y);} int check(int x) { int re=-1,now=0; for(int i=0;i<n;i++) { if(ht[i]>=x) now++; else Max(re,now),now=1; } Max(re,now); return re; } int main() { n=rd();int k=rd(); for(int i=0;i<n;i++) r[i]=rd(); r[n++]=0; build_sa(); int l=0,r=n+1; while(l<r) { int mid=(l+r)>>1; if(check(mid)>=k) l=mid+1; else r=mid; } l--; cout << l << endl ; return 0; }
小結:後綴數組有很多特別有趣的妙用,要多積累啊!因為開$iostream$的緣故所以不能有變量叫做$ws$,我就叫$Ws$了……
[bzoj1717][Usaco2006 Dec]Milk Patterns 產奶的模式_後綴數組_二分答案