1. 程式人生 > >bzoj 2251[2010Beijing Wc]外星聯絡

bzoj 2251[2010Beijing Wc]外星聯絡

www. href gpo max line lin cst clu 全部

題目鏈接

bzoj2251 [2010Beijing Wc]外星聯絡

題解

求出height數組後
對與一個串的存在性
畫出圖來好理解一些,emmmmm,我就不畫了
height[i+1]的值比height[i]要大,說明後綴i與後綴i-1的子串全部包含在i+1中
嗯,剩下的不好說辣,看代碼理解吧

代碼

#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn = 600007;
int n,m,k;
char c[maxn];
int s[maxn],height[maxn],rank[maxn],sa[maxn],saf[maxn],cnt[maxn];
void
rsort() { for(int i=0;i<=m;++i) cnt[i]=0; for(int i=1;i<=n;++i) cnt[rank[saf[i]]]++; for(int i=1;i<=m;++i) cnt[i]+=cnt[i-1]; for(int i=n;i>=1;--i) sa[cnt[rank[saf[i]]]--]=saf[i]; } bool cmp(int *f,int x,int y,int w) { return f[x]==f[y]&&f[x+w]==f[y+w]; } void get_sa() { for
(int i=1;i<=n;++i)rank[i]=s[i],saf[i]=i;m=127;rsort(); for(int p=1,w=1,i;p<n;w<<=1,m=p) { for(i=n-w+1,p=0;i<=n;++i)saf[++p]=i; for(i=1;i<=n;++i)if(sa[i]>w)saf[++p]=sa[i]-w; rsort();std::swap(rank,saf);rank[sa[1]]=p=1; for(i=2;i<=n;++i)rank[sa[i]]=cmp(saf,sa[i],sa[i-1
],w)?p:++p; } int j,k_=0; for(int i=1;i<=n;height[rank[i++]]=k_) for(k_=k_?k_-1:k_,j=sa[rank[i]-1];s[i+k_]==s[j+k_];++k_); } void init() { scanf("%d",&n); scanf("%s",c+1); for(int i=1;i<=n;++i)s[i]=c[i]; s[0]=s[n+1]=-1; } int q[maxn]; void solve() { for(int i=0;i<=n;++i) { for(int j=1+height[i];;j++) { int cnt=1; for(int k=i+1;height[k]>=j;++k,++cnt); if(cnt>1)printf("%d\n",cnt); else break; } } } int main() { init(); get_sa(); solve(); return 0; }

bzoj 2251[2010Beijing Wc]外星聯絡