zoukankan      html  css  js  c++  java
  • BZOJ 2251 [2010Beijing Wc]外星联络

    Description

    小 P 在看过电影《超时空接触》(Contact)之后被深深的打动,决心致力于寻
    找外星人的事业。于是,他每天晚上都爬在屋顶上试图用自己的收音机收听外星
    人发来的信息。虽然他收听到的仅仅是一些噪声,但是他还是按照这些噪声的高
    低电平将接收到的信号改写为由 0 和 1 构成的串, 并坚信外星人的信息就隐藏在
    其中。他认为,外星人发来的信息一定会在他接受到的 01 串中重复出现,所以
    他希望找到他接受到的 01 串中所有重复出现次数大于 1 的子串。但是他收到的
    信号串实在是太长了,于是,他希望你能编一个程序来帮助他。

    Input

    输入文件的第一行是一个整数N ,代表小 P 接收到的信号串的长度。 
    输入文件第二行包含一个长度为N 的 01 串,代表小 P 接收到的信号串。

    Output

    输出文件的每一行包含一个出现次数大于1 的子串所出现的次数。输出的顺
    序按对应的子串的字典序排列。

    Sample Input

    7
    1010101

    Sample Output

    3
    3
    2
    2
    4
    3
    3
    2
    2

    HINT

      对于 100%的数据,满足 0 <=  N     <=3000 

    Source

     
    做这道题之前我们需要首先明白一件事情
    所有后缀的前缀是字符串的子串
    这样我们就把子串的出现资次数转换成了求后缀的前缀的出现次数的问题
    在后缀的前缀上搞事情,这会让你想到什么?
    没错!后缀数组的Height数组
    我们可以在Height数组里面枚举
    字典序的话好处理,Height数组就是按字典序排的
    首先枚举排名,在Height数组中不断枚举前缀,对于每一个前缀,不断往后枚举Height,枚举的时候统计次数。
    哎呀说的好乱,自己看代码把
     
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int MAXN=2*1e6+10;
    int sa[MAXN],rak[MAXN],tp[MAXN],tax[MAXN],a[MAXN],N,M,height[MAXN];
    char s[MAXN];
    void Qsort()
    {
        for(int i=1;i<=M;i++) tax[i]=0;
        for(int i=1;i<=N;i++) tax[rak[i]]++;
        for(int i=1;i<=M;i++) tax[i]+=tax[i-1];
        for(int i=N;i>=1;i--) sa[ tax[rak[tp[i]]]-- ] = tp[i];
    }
    void Ssort()
    {
        M=127;
        for(int i=1;i<=N;i++) rak[i]=a[i],tp[i]=i;Qsort();
        for(int w=1,p=1; p<N ; w<<=1,M=p)
        {
            p=0;
            for(int i=N-w+1;i<=N;i++) tp[++p]=i;
            for(int i=1;i<=N;i++) if(sa[i]>w) tp[++p]=sa[i]-w;
            Qsort();
            swap(tp,rak);
            rak[sa[1]]=1;p=1;
            for(int i=2;i<=N;i++) rak[sa[i]] = (tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+w]==tp[sa[i-1]+w])?p:++p;
        }
        int j,k=0;
        for(int i=1;i<=N;height[rak[i++]]=k)
            for(k=k?k-1:k,j=sa[rak[i]-1];a[i+k]==a[j+k];++k );
        for(int i=0;i<=N;i++)
        {
            for(int j=height[i]+1;;j++)
            {
                int tot=1;
                for(int k=i+1;height[k]>=j;++k,++tot);
                if(tot>1) printf("%d
    ",tot);
                else break;
            }
        }
    }
    int main()
    {
        #ifdef WIN32
        freopen("a.in","r",stdin);
        #else
        #endif
        int Meiyong;
        cin>>Meiyong;
        scanf("%s",s);
        N=strlen(s);
        for(int i=1;i<=N;i++) a[i]=s[i-1];
        Ssort();
        return 0;
    }
     
     
     
     
  • 相关阅读:
    iap 详细
    血的教训,下次开工程 一点要写好判断空字符串方法
    iOS中的ScrollView
    自定义弹框加载方式
    CAGradientLayer简介(处理视图渐变色)
    iOS 制作view渐变的效果CAGradientLayer
    将vs2012的项目转化成VS2010
    关于Excel导入的HDR=YES; IMEX=1详解
    C#读取Excel表中的数据时,为何有些行的字段内容读取不到
    OLEDB读取EXCEL表格时,某些字段为空,怎么办?
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/8430014.html
Copyright © 2011-2022 走看看