• Bzoj2251 [2010Beijing Wc]外星联络


    Time Limit: 30 Sec  Memory Limit: 256 MB
    Submit: 867  Solved: 522

    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

    建出后缀数组,然后按rank从大到小的顺序,根据height数组暴力查值。具体见代码。

    夜常视力骤降,查错无力。r[]数组下标打岔一位半天没看出来。

    然后玩了一发输出优化,输出x的时候忘了%10,尴尬

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 using namespace std;
     9 const int mxn=5010;
    10 int read(){
    11     int x=0,f=1;char ch=getchar();
    12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 void write(int x){
    17     if(x>9)write(x/10);
    18     putchar('0'+x%10);
    19     return;
    20 }
    21 int sa[mxn],rk[mxn],ht[mxn],r[mxn];
    22 int wa[mxn],wb[mxn],wv[mxn],cnt[mxn];
    23 char s[mxn];
    24 inline int cmp(int *r,int a,int b,int l){
    25     return r[a]==r[b] && r[a+l]==r[b+l];
    26 }
    27 void GetSA(int *sa,int n,int m){
    28     int i,j,k;
    29     int *x=wa,*y=wb;
    30     for(i=0;i<m;i++)cnt[i]=0;
    31     for(i=0;i<n;i++)cnt[x[i]=r[i]]++;
    32     for(i=1;i<m;i++)cnt[i]+=cnt[i-1];
    33     for(i=n-1;i>=0;i--)sa[--cnt[x[i]]]=i;
    34     for(int j=1,p=0;p<n;j<<=1,m=p){
    35         for(p=0,i=n-j;i<n;i++)y[p++]=i;
    36         for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
    37         for(i=0;i<n;i++)
    38             wv[i]=x[y[i]];
    39         for(i=0;i<m;i++)cnt[i]=0;
    40         for(i=0;i<n;i++)cnt[wv[i]]++;
    41         for(i=1;i<m;i++)cnt[i]+=cnt[i-1];
    42         for(i=n-1;i>=0;i--)sa[--cnt[wv[i]]]=y[i];
    43         swap(x,y);
    44         p=1;x[sa[0]]=0;
    45         for(i=1;i<n;i++)
    46             x[sa[i]]=cmp(y,sa[i],sa[i-1],j)?p-1:p++;
    47     }
    48     return;
    49 }
    50 void GetHt(int n){
    51     int i,j,k=0;
    52     for(i=1;i<=n;i++)rk[sa[i]]=i;
    53     for(i=0;i<n;i++){
    54         if(k)k--;
    55         j=sa[rk[i]-1];
    56         while(s[i+k]==s[j+k])k++;
    57         ht[rk[i]]=k;
    58     }
    59     return;
    60 }
    61 int n,m;
    62 int ans[mxn],mct=0;
    63 int main(){
    64     int i,j;
    65     n=read();
    66     scanf("%s",s);
    67     for(i=0;i<n;i++)r[i]=s[i]-'0'+1;//
    68     GetSA(sa,n+1,5);
    69     GetHt(n);
    70     //
    71 //    for(i=1;i<=n;i++)printf("%d ",sa[i]);puts("");
    72 //    for(i=0;i<n;i++)printf("%d ",rk[i]);puts("");
    73 //    for(i=0;i<n;i++)printf("%d ",ht[i]);puts("");
    74     for(i=1;i<=n;i++){
    75         for(j=ht[i]+1;sa[i]+j-1<=n;j++){
    76             int l,r;
    77             for(l=i;l>=1 && ht[l]>=j;l--);
    78             for(r=i+1;r<=n &&ht[r]>=j;r++);
    79             if(r-l>1){write(r-l);puts("");}
    80         }
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    2019.6.15刷题统计
    入门组完成情况
    2019.6.14刷题统计
    2019.6.13刷题统计
    绑定与非绑定方法 继承 继承与抽象 查找属性关系 派生与覆盖 访问父类的内容
    23 xml 面向对象
    day22 configparser模块 subprocsee模块 表格
    Python常用模块
    20.logging日志 re正则
    导入模块 包
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6648712.html
Copyright © 2020-2023  润新知