bzoj 2251(后缀数组)
2016-04-15 19:32
211 查看
2251: [2010Beijing Wc]外星联络
Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 660 Solved: 388
[Submit][Status][Discuss]
Description
小 P 在看过电影《超时空接触》(Contact)之后被深深的打动,决心致力于寻找外星人的事业。于是,他每天晚上都爬在屋顶上试图用自己的收音机收听外星
人发来的信息。虽然他收听到的仅仅是一些噪声,但是他还是按照这些噪声的高
低电平将接收到的信号改写为由 0 和 1 构成的串, 并坚信外星人的信息就隐藏在
其中。他认为,外星人发来的信息一定会在他接受到的 01 串中重复出现,所以
他希望找到他接受到的 01 串中所有重复出现次数大于 1 的子串。但是他收到的
信号串实在是太长了,于是,他希望你能编一个程序来帮助他。
Input
输入文件的第一行是一个整数N ,代表小 P 接收到的信号串的长度。输入文件第二行包含一个长度为N 的 01 串,代表小 P 接收到的信号串。
Output
输出文件的每一行包含一个出现次数大于1 的子串所出现的次数。输出的顺序按对应的子串的字典序排列。
Sample Input
71010101
Sample Output
33
2
2
4
3
3
2
2
HINT
对于 100%的数据,满足 0 <= N <=3000解题思路:后缀数组然后暴力。细节有点恶心
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n,k;
char s[3001];
int sa[3001],rank[3001],height[3001],zan[3001],dis[3001];
inline int read()
{
char y; int x=0,f=1; y=getchar();
while (y<'0' ||y>'9') {if (y=='-') f=-1; y=getchar();}
while (y>='0' && y<='9') {x=x*10+int(y)-48; y=getchar();}
return x*f;
}
bool cmp(int x,int y)
{
if (rank[x]<rank[y])return true;
if (rank[x]==rank[y])
{
int u1,u2;
if (x+k<=n) u1=rank[x+k];else u1=-1;
if (y+k<=n) u2=rank[y+k];else u2=-1;
return u1<u2;
}
return false;
}
void makeheight()
{
int j=0;
for (int i=1;i<=n;++i)
{
if (j)--j;
int u1=sa[rank[i]+1];
if (u1==0)continue;
while (i+j<=n && u1+j<=n && s[i+j-1]==s[u1+j-1]) ++j;
height[rank[i]]=j;
}
}
int main()
{
n=read();
scanf("%s",s);
for (int i=1;i<=n;++i)
{
sa[i]=i; rank[i]=int(s[i-1]);
}
for (k=1;k<=n;k=k*2)
{
sort(sa+1,sa+n+1,cmp);
zan[sa[1]]=1;
for (int i=2;i<=n;++i)
{
if (cmp(sa[i-1],sa[i])) zan[sa[i]]=zan[sa[i-1]]+1;else
zan[sa[i]]=zan[sa[i-1]];
}
for (int i=1;i<=n;++i)
rank[i]=zan[i];
}
makeheight();
memset(zan,0,sizeof(zan));
for (int i=1;i<=n-1;++i)
{
memset(dis,0,sizeof(dis));
memset(sa,0,sizeof(sa));
int mx=height[i]; dis[mx]=1; ++sa[mx];
for (int j=i+1;j<=n-1;++j)
{
mx=min(mx,height[j]);
++dis[mx]; ++sa[mx];
}
for (int j=n-1;j>=1;--j)
{
zan[j]+=zan[j+1];
dis[j]+=dis[j+1]-zan[j];
}
for (int j=1;j<=n;++j)
{
if (dis[j]+1>1)printf("%d\n",dis[j]+1);
zan[j]=sa[j];
}
}
}
相关文章推荐
- 如何更方便快捷的调用restful服务
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- PAT1003.我要通过!(20)(简单的c语言风格c++解法)
- iOS个人整理39-cocoaPods的使用
- 在Eclipse环境下编写ABAP程序
- 网站的email地址
- ArcGIS Runtime SDK for iOS(三) --- Callout的自定义属性展示
- JavaSE学习小笔记(2)
- Training Deep Neural Networks
- CFA. Co-prime Array
- Android的.so文件、ABI和CPU的关系
- 汉诺塔
- android一些常用事件