[bzoj2251][后缀数组][2010Beijing Wc]外星联络
来源:互联网 发布:扒谱子软件 编辑:程序博客网 时间:2024/05/16 15:28
2251: [2010Beijing Wc]外星联络
Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 916 Solved: 556
[Submit][Status][Discuss]
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
sol:
发现是求本质不同的子串的出现次数。要求字典序,所以在后缀数组上走。并且只能做前缀,因为前缀我们能保证字典序。
接着考虑一个sa[i]提供的贡献,如果hei[i]>hei[i-1]的话,说明出现了一个新的子串,那这个子串已经出现在了i-1和i(并且不会出现在更前面,这个显然),我们考虑这个子串出现了几次,显然只要往后走一走,看一下hei有没有比这个子串大就行了
#include<cstdio>#include<algorithm>#include<string>#include<cstring>#include<cstdlib>#include<cmath>#include<iostream>using namespace std;int n,m;inline int read(){ char c; int res,flag=0; while((c=getchar())>'9'||c<'0') if(c=='-')flag=1; res=c-'0'; while((c=getchar())>='0'&&c<='9') res=(res<<3)+(res<<1)+c-'0'; return flag?-res:res;}const int N=3100;int sa[N],rank[N],w[N],Max,x[N],hei[N]; char sr[N];inline void Sa(){ int j,u,v,m=127,cnt; for(int i=1;i<=n;++i) w[x[i]=sr[i]]++; for(int i=1;i<=m;++i) w[i]+=w[i-1]; for(int i=n;i>=1;--i) sa[w[x[i]]--]=i; for(j=1;;j<<=1) { cnt=0; for(int i=n-j+1;i<=n;++i) rank[++cnt]=i; for(int i=1;i<=n;++i) if(sa[i]>j) rank[++cnt]=sa[i]-j; for(int i=1;i<=m;++i) w[i]=0; for(int i=1;i<=n;++i) w[x[i]]++; for(int i=1;i<=m;++i) w[i]+=w[i-1]; for(int i=n;i>=1;--i) sa[w[x[rank[i]]]--]=rank[i]; m=0; for(int i=1;i<=n;++i) { u=sa[i];v=sa[i-1]; if(x[u]!=x[v]||x[u+j]!=x[v+j]) ++m; rank[u]=m; } if(m==n) break; for(int i=1;i<=n;++i) x[i]=rank[i]; } j=0; for(int i=1;i<=n;++i) { v=sa[rank[i]-1]; j=max(j-1,0); while(sr[i+j]==sr[v+j]) ++j; hei[rank[i]]=j; }}int main(){// freopen("2251.in","r",stdin);// freopen(".out","w",stdout); n=read(); scanf("%s",sr+1); for(int i=1;i<=n;++i) sr[i]++; Sa(); int pos,high=0,ans; for(int i=2;i<=n;++i) { if(hei[i]>hei[i-1]) for(int j=high+1;j<=hei[i];++j) { pos=i; ans=1; while(hei[pos]>=j) ans++,pos++; printf("%d\n",ans); } high=hei[i]; } }
- [BZOJ2251][2010Beijing Wc]外星联络(后缀数组)
- BZOJ2251: [2010Beijing Wc]外星联络 后缀数组
- bzoj2251[2010Beijing Wc]外星联络 后缀数组
- bzoj2251 [2010Beijing WC]外星联络(后缀数组+暴力)
- [bzoj2251][后缀数组][2010Beijing Wc]外星联络
- [2010Beijing Wc]外星联络 后缀数组
- BZOJ2251——[2010Beijing Wc]外星联络
- 2251: [2010Beijing Wc]外星联络 后缀数组
- BZOJ 2251: [2010Beijing Wc]外星联络|后缀数组
- BZOJ 2251 Beijing WC 2010 外星联络 后缀数组
- 【BZOJ 2251】[2010Beijing Wc]外星联络 后缀数组
- bzoj 2251: [2010Beijing Wc]外星联络 (后缀数组)
- 【BZOJ2251】外星联络 后缀数组
- [2010Beijing Wc]外星联络
- BZOJ 2251 2010Beijing WC 外星联络 后缀数组/Trie树
- BZOJ 2251 [2010Beijing Wc]外星联络
- BZOJ 2251 [2010Beijing Wc]外星联络
- bzoj 2251 [2010Beijing Wc]外星联络
- 一键重装系统,装机员一键重装最新版
- JavaScript权威指南读书笔记—— 模块
- Leetcode 刷题 Day4 136.SingleNumber
- composer 安装laravel指定版本
- List接口的ArrayList的使用
- [bzoj2251][后缀数组][2010Beijing Wc]外星联络
- Tradingview做好交易图表工具(一)
- tf.matrix_diag和tf.matrix_inverse的用法(tensorflow如何生成对角矩阵和求逆矩阵)
- 分布式节点协调实现方式
- opencv bug集合
- FRI.Device.Rating.Program.2.0.
- PHP 实现多文件上传功能
- 有限状态机求解字符串匹配问题
- 笔记---上传下载代码