POJ - 1226 Substrings (后缀数组)
传送门:POJ - 1226
这个题跟POJ - 3294 和POJ - 3450 都是一样的思路,一种题型。
POJ - 3294的题解可以见:https://www.cnblogs.com/lilibuxiangtle/p/12649853.html
题意:给你n个字符串,求最长子串的长度,要求子串或子串的翻转串在n个字符串中都出现。
题解:把每个字符串和字符串的翻转串连接起来,中间用不同且没出现过的字符隔开,然后再把n个字符串和翻转的串连到一起。然后后缀数组求出sa数组和height数组,用be数组标记每个位置的字符在哪个串中。二分长度,vis数组标记符合条件的串,cnt记录个数,如果cnt>=n则说明该长度可以,反之则不行。(重点!!vis及时标记 我憨憨的wa了好几发,找了快三个小时)
1 #include<cstdio>
2 #include<algorithm>
3 #include<queue>
4 #include<iostream>
5 #include<cmath>
6 #include<cstring>
7 using namespace std;
8
9 //sa:字典序中排第i位的起始位置在str中第sa[i] sa[1~n]为有效值
10
11 //rnk:就是str第i个位置的后缀是在字典序排第几 rnk[0~n-1]为有效值
12
13 //height:字典序排i和i-1的后缀的最长公共前缀 height[2~n]为有效值,第二个到最后一个
14
15 const int INF=0x3f3f3f3f;
16 const int maxn = 1e5+10;
17 int wa[maxn],wb[maxn],wsf[maxn],wv[maxn],sa[maxn];
18 int rnk[maxn],height[maxn];
19 char s[maxn];
20 int r[maxn],n,L;
21 int be[maxn],vis[110];
22
23 int cmp(int *r,int a,int b,int k)
24 {
25 return r[a]==r[b]&&r[a+k]==r[b+k];
26 }
27
28 void getsa(int *r,int *sa,int n,int m)//n为添加0后的总长
29 {
30 int i,j,p,*x=wa,*y=wb,*t;
31 for(i=0; i<m; i++) wsf[i]=0;
32 for(i=0; i<=n; i++) wsf[x[i]=r[i]]++;
33 for(i=1; i<m; i++) wsf[i]+=wsf[i-1];
34 for(i=n; i>=0; i--) sa[--wsf[x[i]]]=i;
35 p=1;
36 j=1;
37 for(; p<=n; j*=2,m=p){
38 for(p=0,i=n+1-j; i<=n; i++) y[p++]=i;
39 for(i=0; i<=n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
40 for(i=0; i<=n; i++) wv[i]=x[y[i]];
41 for(i=0; i<m; i++) wsf[i]=0;
42 for(i=0; i<=n; i++) wsf[wv[i]]++;
43 for(i=1; i<m; i++) wsf[i]+=wsf[i-1];
44 for(i=n; i>=0; i--) sa[--wsf[wv[i]]]=y[i];
45 swap(x,y);
46 x[sa[0]]=0;
47 for(p=1,i=1; i<=n; i++)
48 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++;
49 }
50 }
51
52 void getheight(int *r,int n)//n为添加0后的总长
53 {
54 int i,j,k=0;
55 for(i=1; i<=n; i++) rnk[sa[i]]=i;
56 for(i=0; i<n; i++){
57 if(k)
58 k--;
59 else
60 k=0;
61 j=sa[rnk[i]-1];
62 while(r[i+k]==r[j+k])
63 k++;
64 height[rnk[i]]=k;
65 }
66 }
67
68 bool check(int k)
69 {
70 memset(vis,0,sizeof(vis));
71 int cnt=0;
72 for(int i=2;i<=L;i++){
73 if(height[i]>=k){
74 if(!vis[be[sa[i]]]) cnt++;
75 vis[be[sa[i]]]=1; //就是这个地方卡了我快3个小时!!!
76 if(!vis[be[sa[i-1]]]) cnt++;
77 vis[be[sa[i-1]]]=1;
78 }
79 else {
80 memset(vis,0,sizeof(vis));
81 cnt=0;
82 }
83 if(cnt>=n) return 1;
84 }
85 return 0;
86 }
87
88 int main()
89 {
90 ios::sync_with_stdio(false);
91 cin.tie(0);
92 cout.tie(0);
93 int t;
94 cin>>t;
95 while(t--){
96 cin>>n;
97 L=0;
98 for(int i=0;i<n;i++){
99 cin>>s;
100 int len=strlen(s);
101 for(int j=0;j<len;j++){
102 r[L]=s[j];
103 be[L++]=i;
104 }
105 r[L]=i+200;
106 be[L++]=i;
107 for(int j=len-1;j>=0;j--){
108 r[L]=s[j];
109 be[L++]=i;
110 }
111 if(i!=n-1) r[L]=i+n+200,be[L++]=i;
112 }
113 if(n==1) {
114 cout<<strlen(s)<<endl;
115 continue;
116 }
117 r[L]=0;
118 getsa(r,sa,L,500);
119 getheight(r,L);
120 int l=0,r=105,ans=0;
121 while(l<=r){
122 int mid=l+r>>1;
123 if(check(mid)) ans=mid,l=mid+1;
124 else r=mid-1;
125 }
126 cout<<ans<<endl;
127 }
128 return 0;
129 }
POJ - 1226 Substrings (后缀数组)的更多相关文章
- POJ 1226 Substrings(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=1226 [题目大意] 求在每个给出字符串中出现的最长子串的长度,字符串在出现的时候可以是倒置的. [题解] 我们将每个字符串倒置,用 ...
- poj 3415 Common Substrings——后缀数组+单调栈
题目:http://poj.org/problem?id=3415 因为求 LCP 是后缀数组的 ht[ ] 上的一段取 min ,所以考虑算出 ht[ ] 之后枚举每个位置作为右端的贡献. 一开始想 ...
- poj 3415 Common Substrings —— 后缀数组+单调栈
题目:http://poj.org/problem?id=3415 先用后缀数组处理出 ht[i]: 用单调栈维护当前位置 ht[i] 对之前的 ht[j] 取 min 的结果,也就是当前的后缀与之前 ...
- POJ 3415 Common Substrings 后缀数组+并查集
后缀数组,看到网上很多题解都是单调栈,这里提供一个不是单调栈的做法, 首先将两个串 连接起来求height 求完之后按height值从大往小合并. height值代表的是 sa[i]和sa[i ...
- POJ - 3415 Common Substrings (后缀数组)
A substring of a string T is defined as: T( i, k)= TiTi +1... Ti+k -1, 1≤ i≤ i+k-1≤| T|. Given two s ...
- POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数
题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS Memory Limit: 65536K ...
- POJ 2406 KMP/后缀数组
题目链接:http://poj.org/problem?id=2406 题意:给定一个字符串,求由一个子串循环n次后可得到原串,输出n[即输出字符串的最大循环次数] 思路一:KMP求最小循环机,然后就 ...
- Maximum repetition substring(POJ - 3693)(sa(后缀数组)+st表)
The repetition number of a string is defined as the maximum number \(R\) such that the string can be ...
- UVALive - 6869 Repeated Substrings 后缀数组
题目链接: http://acm.hust.edu.cn/vjudge/problem/113725 Repeated Substrings Time Limit: 3000MS 样例 sample ...
随机推荐
- 简要MR与Spark在Shuffle区别
一.区别 ①本质上相同,都是把Map端数据分类处理后交由Reduce的过程. ②数据流有所区别,MR按map, spill, merge, shuffle, sort, r educe等各阶段逐一实现 ...
- P1967 货车运输(倍增LCA,生成树)
题目链接: https://www.luogu.org/problemnew/show/P1967 题目描述 A国有n座城市,编号从 1到n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制, ...
- 强制删除 Terminating 状态的pod
[root@k8s-master coredns]# kubectl get podNAME READY STATUS RESTARTS ...
- 详解MySQL执行事务的语法和流程
摘要:MySQL 提供了多种存储引擎来支持事务. MySQL 提供了多种存储引擎来支持事务.支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 ...
- linux下安装nacos
一.安装 1.下载安装包: https://github.com/alibaba/nacos/releases 2.解压 : tar -xzvf nacos-server-1.2.1.tar.gz 3 ...
- 干电池升压IC
1, 干电池升压IC 升压输出3V,3,3V,5V等3V-5V可调 2, 单节锂电池升压IC 升压输出4.2 ...
- nokogiri Fail install on Ruby 2.3 for Windows #1456 <From github>
Q: gem install railson nokogiri install fail with error: 'nokogiri requires Ruby version < 2.3, & ...
- 我教你如何解决 Docker 下载 mcr.microsoft.com 镜像慢的办法
我教你如何解决 Docker 下载 mcr.microsoft.com 镜像慢的办法 一.介绍 最近,我在写有关使用 Jenkins 搭建企业级持续集成环境的文章,准备了四台服务器,企业级别嘛,一台就 ...
- Any race is a bug. When there is a race, the compiler is free to do whatever it wants.
https://mp.weixin.qq.com/s/pVJiFdDDKVx707eKL19bjA 谈谈 Golang 中的 Data Race 原创 ms2008 poslua 2019-05-13 ...
- 监听套接字描述字 已连接套接字描述字 和打电话的情形非常不一样的地方 完成了 TCP 三次握手,操作系统内核就为这个客户生成一个已连接套接字
1. accept: 电话铃响起了-- 当客户端的连接请求到达时,服务器端应答成功,连接建立,这个时候操作系统内核需要把这个事件通知到应用程序,并让应用程序感知到这个连接.这个过程,就好比电信运营商完 ...