bzoj 2251[2010Beijing Wc]外星联络

Posted Nico&11101001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2251[2010Beijing Wc]外星联络相关的知识,希望对你有一定的参考价值。

题目链接

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]外星联络的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2251: [2010Beijing Wc]外星联络

bzoj2251 [2010Beijing Wc]外星联络

bzoj 2251[2010Beijing Wc]外星联络

Bzoj2251 [2010Beijing Wc]外星联络

2251. [2010Beijing Wc]外星联络后缀数组

BZOJ2253[2010 Beijing wc]纸箱堆叠 cdq分治