BZOJ 2251 [2010Beijing Wc]外星联络
时间:2022-05-08
本文章向大家介绍BZOJ 2251 [2010Beijing Wc]外星联络,主要内容包括Description、Input、Output、Sample Input、Sample Output、HINT、Source、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
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("%dn",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;
}
- Ajax请求过程中显示“进度”的简单实现
- ASP.NET MVC基于标注特性的Model验证:ValidationAttribute
- 【深度学习系列】卷积神经网络详解(二)——自己手写一个卷积神经网络
- 区块链钱包mMoney向GooglePay、Applepay发起挑战
- Model验证系统运行机制是如何实现的?
- CentOS 6.8 部署zookeeper集群
- ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidator
- 使用容器进行应用程序路由
- MVVM(Knockout.js)的新尝试:多个Page,一个ViewModel
- ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidatorProviders
- 我所理解的RESTful Web API [设计篇]
- 黑箱难题阻碍了深度学习的普及与发展
- iOS 转场动画探究(一)
- XCode中如何使用事务
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法