• 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;
    }
     
     
     
     
  • 相关阅读:
    Maven的pom文件依赖提示 ojdbc6 Missing artifact,需要手动下载并导入maven参考
    Maven全局配置文件settings.xml详解(转)
    SpringBoot -- 项目结构+启动流程
    64匹马,8个赛道,找出前4名最少比赛多少场?——最快10次,最慢11次;
    Spring家族主流成员介绍
    java 中文与unicode互转
    Netty的Marshalling编解码器
    解决svn迁移过程中出现:SVN Error: is not the same repository as的问题
    netty入门实例
    Dubbo的使用及原理
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/8430014.html
Copyright © 2020-2023  润新知