bzoj 2251(后缀数组)
来源:互联网 发布:淘宝如何开话费充值 编辑:程序博客网 时间:2024/04/30 01:25
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
1010101
Sample Output
3
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];
}
}
}
- bzoj 2251(后缀数组)
- bzoj 2251 后缀数组
- 【bzoj 1692】后缀数组
- BZOJ 1031后缀数组
- bzoj 2119 后缀数组
- BZOJ 3230 后缀数组+ST
- BZOJ 3796 后缀数组+KMP
- BZOJ 2251: [2010Beijing Wc]外星联络|后缀数组
- BZOJ 2251 Beijing WC 2010 外星联络 后缀数组
- 【BZOJ 2251】[2010Beijing Wc]外星联络 后缀数组
- bzoj 2251: [2010Beijing Wc]外星联络 (后缀数组)
- 后缀数组练习题bzoj 1031 后缀数组模板题目
- BZOJ 3172 Tjoi2013 单词 后缀数组
- BZOJ 1692 队列变换 贪心+后缀数组
- BZOJ 2119 股市的预测 后缀数组
- BZOJ 2946 [Poi2000]公共串 后缀数组
- BZOJ 3796 Mushroom追妹纸 后缀数组+KMP
- BZOJ 4278 ONTAK2015 Tasowanie 后缀数组
- ArcGIS Runtime SDK for iOS(三) --- Callout的自定义属性展示
- UVA 10651 Pebble Solitaire
- 网站的email地址
- 在Eclipse环境下编写ABAP程序
- iOS-开发
- bzoj 2251(后缀数组)
- PAT1003.我要通过!(20)(简单的c语言风格c++解法)
- Hadoop初识--Hadoop单机模式安装和环境配置
- UITableViewCell左滑动删除 和cell上按钮的点击事件
- CentOS下Redis服务器安装配置
- RxAndroid + Retrofit + Databinding
- 八皇后问题
- 剑指offer之面试题7:用两个栈实现队列
- 更新 FrameWork