当前位置: 首页 > news >正文

2251. [2010Beijing Wc]外星联络【后缀数组】

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

 

这个题是bzoj权限题QvQ
于是只好自己和hzwer学长的标称对拍
其实一开始我的思路是差不多的
构造后缀数组,字典序为SA,然后随便枚举一下
只不过我忽略了一个重要的性质
使得我的效率变成了O(n^3)
然而只要用到下面这个性质,效率就只有O(n^2):
因为子串是后缀的前缀,
而SA[i]和SA[i-1]的前height[i]位本质又是相同的,
因重复的子串在SA[i-1]已经往后扫过了
所以串SA[i]只需要判断height[i]+1位~最后一位构成的前缀能往后扩展多少即可。
原因:每个子串只出现过一次,共n^2个子串

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define MAXN (3000+10)
 5 using namespace std;
 6 int wa[MAXN],wb[MAXN],wt[MAXN];
 7 char r[MAXN];
 8 int Height[MAXN],SA[MAXN],Rank[MAXN];
 9 int n,m=130; 
10 
11 bool cmp(int *y,int a,int b,int k)
12 {
13     int arank1=y[a];
14     int brank1=y[b];
15     int arank2=a+k>=n?-1:y[a+k];
16     int brank2=b+k>=n?-1:y[b+k];
17     return arank1==brank1 && arank2==brank2;
18 }
19 
20 void Build_SA()
21 {
22     int *x=wa,*y=wb;
23     for (int i=0;i<m;++i) wt[i]=0;
24     for (int i=0;i<n;++i) wt[x[i]=r[i]]++;
25     for (int i=1;i<m;++i) wt[i]+=wt[i-1];
26     for (int i=n-1;i>=0;--i) SA[--wt[x[i]]]=i;
27     
28     for (int j=1;j<=n;j<<=1)
29     {
30         int p=0;
31         for (int i=n-j;i<n;++i) y[p++]=i;
32         for (int i=0;i<n;++i) if (SA[i]>=j) y[p++]=SA[i]-j;
33         
34         for (int i=0;i<m;++i) wt[i]=0;
35         for (int i=0;i<n;++i) wt[x[y[i]]]++;
36         for (int i=1;i<m;++i) wt[i]+=wt[i-1];
37         for (int i=n-1;i>=0;--i) SA[--wt[x[y[i]]]]=y[i];
38         
39         m=1;swap(x,y);
40         x[SA[0]]=0;
41         for (int i=1;i<n;++i)
42             x[SA[i]]=cmp(y,SA[i],SA[i-1],j)?m-1:m++;
43         if (m>=n) break;
44     }
45 }
46 
47 void Build_Height()
48 {
49     for (int i=0;i<n;++i) Rank[SA[i]]=i;
50     Height[0]=0;
51     int k=0;
52     for (int i=0;i<n;++i)
53     {
54         if (!Rank[i]) continue;
55         if (k) k--;
56         int j=SA[Rank[i]-1];
57         while (r[i+k]==r[j+k]) ++k;
58         Height[Rank[i]]=k;
59     }
60 }
61 
62 int main()
63 {
64     scanf("%d%s",&n,r);
65     Build_SA();
66     Build_Height();
67     for (int i=0;i<n-1;++i)
68     {
69         for (int j=Height[i]+1;j<=n-SA[i];++j)//这里非常的妙啊 
70         {
71             int k=i+1;
72             while (Height[k]>=j) ++k;
73             if (k-i>1) printf("%d\n",k-i);
74         }
75     }
76 }

转载于:https://www.cnblogs.com/refun/p/8679064.html

相关文章:

  • Tortoisesvn,鼠标右键菜单中找不到“检出”的处理方法
  • 麻烦大家反馈一下昨天的网站访问速度
  • 网关 Spring-Cloud-Gateway 源码解析 —— 网关初始化
  • shell中quotes的不同作用
  • C/C++入门必备
  • SqlServer在表中插入数据时出现主键冲突问题解决方式
  • 1、告别windows,决定
  • 深入浅出Power Shell——cmd调用PowerShell脚本
  • 专访黄隽实:Stay hungry, Stay foolish!
  • golang中应该怎么使用socket?
  • 第十一课 xshell实现linux与windows互文件、用户与密码的配置文件、用户和用户组的管理...
  • ubuntu12.04+ssh远程登录
  • 生活在这个世界当中,就要学会去接受去应用,去感受。。。。。
  • JavaWeb(学习笔记二)
  • 设置位置在JavaFX中使用物理引擎JBox2D
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 【391天】每日项目总结系列128(2018.03.03)
  • CSS3 变换
  • docker-consul
  • HTML5新特性总结
  • JAVA 学习IO流
  • JavaScript学习总结——原型
  • Java读取Properties文件的六种方法
  • leetcode讲解--894. All Possible Full Binary Trees
  • React+TypeScript入门
  • Redis在Web项目中的应用与实践
  • scrapy学习之路4(itemloder的使用)
  • SpiderData 2019年2月13日 DApp数据排行榜
  • 服务器从安装到部署全过程(二)
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 每天一个设计模式之命令模式
  • 前端存储 - localStorage
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 探索 JS 中的模块化
  • 通过git安装npm私有模块
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 线上 python http server profile 实践
  • 硬币翻转问题,区间操作
  • 栈实现走出迷宫(C++)
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • # 计算机视觉入门
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #每天一道面试题# 什么是MySQL的回表查询
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (07)Hive——窗口函数详解
  • (13):Silverlight 2 数据与通信之WebRequest
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (pytorch进阶之路)扩散概率模型
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (四) 虚拟摄像头vivi体验
  • (转)【Hibernate总结系列】使用举例
  • (转)Linq学习笔记
  • (转载)Linux网络编程入门