Bzoj2251 [2010Beijing Wc]外星联络
Posted SilverNebula
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bzoj2251 [2010Beijing Wc]外星联络相关的知识,希望对你有一定的参考价值。
Submit: 867 Solved: 522
Description
小 P 在看过电影《超时空接触》(Contact)之后被深深的打动,决心致力于寻
找外星人的事业。于是,他每天晚上都爬在屋顶上试图用自己的收音机收听外星
人发来的信息。虽然他收听到的仅仅是一些噪声,但是他还是按照这些噪声的高
低电平将接收到的信号改写为由 0 和 1 构成的串, 并坚信外星人的信息就隐藏在
其中。他认为,外星人发来的信息一定会在他接受到的 01 串中重复出现,所以
他希望找到他接受到的 01 串中所有重复出现次数大于 1 的子串。但是他收到的
信号串实在是太长了,于是,他希望你能编一个程序来帮助他。
Input
输入文件的第一行是一个整数N ,代表小 P 接收到的信号串的长度。
输入文件第二行包含一个长度为N 的 01 串,代表小 P 接收到的信号串。
Output
输出文件的每一行包含一个出现次数大于1 的子串所出现的次数。输出的顺
序按对应的子串的字典序排列。
Sample Input
7
1010101
1010101
Sample Output
3
3
2
2
4
3
3
2
2
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 }
以上是关于Bzoj2251 [2010Beijing Wc]外星联络的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 2251: [2010Beijing Wc]外星联络