[Codechef SSTORY] A Story with Strings - 后缀数组,二分
[Codechef SSTORY] A Story with Strings
Description
给定两个字符串,求它们的最长公共子串。如果解不唯一,输出最先在第二个字符串中出现的那个。
Solution
仍然考虑二分答案,然后每次检验连续的一块中是否有来自两个串的后缀出现。
最后额外处理一次,每次检验连续的一块中是否有来自两个串的后缀出现,在有的情况下利用所有来源于第二个串的后缀得到可能的最小位置即可。
竟然二分边界忘记加一,我TM真是个憨憨
#include <bits/stdc++.h>
using namespace std;
int n,l1,l2,m=256,sa[1000005],y[1000005],u[1000005],v[1000005],o[1000005],r[1000005],h[1000005],T;
char str[1000005];
long long ans;
int main()
{
scanf("%s",str+1);
l1=strlen(str+1);
str[l1+1]='$';
scanf("%s",str+l1+2);
l2=strlen(str+l1+2);
n=l1+l2+1;
for(int i=1; i<=n; i++) u[str[i]]++;
for(int i=1; i<=m; i++) u[i]+=u[i-1];
for(int i=n; i>=1; i--) sa[u[str[i]]--]=i;
r[sa[1]]=1;
for(int i=2; i<=n; i++) r[sa[i]]=r[sa[i-1]]+(str[sa[i]]!=str[sa[i-1]]);
for(int l=1; r[sa[n]]<n; l<<=1)
{
memset(u,0,sizeof u);
memset(v,0,sizeof v);
memcpy(o,r,sizeof r);
for(int i=1; i<=n; i++) u[r[i]]++, v[r[i+l]]++;
for(int i=1; i<=n; i++) u[i]+=u[i-1], v[i]+=v[i-1];
for(int i=n; i>=1; i--) y[v[r[i+l]]--]=i;
for(int i=n; i>=1; i--) sa[u[r[y[i]]]--]=y[i];
r[sa[1]]=1;
for(int i=2; i<=n; i++) r[sa[i]]=r[sa[i-1]]+((o[sa[i]]!=o[sa[i-1]])||(o[sa[i]+l]!=o[sa[i-1]+l]));
}
{
int i,j,k=0;
for(int i=1; i<=n; h[r[i++]]=k)
for(k?k--:0,j=sa[r[i]-1]; str[i+k]==str[j+k]; k++);
}
int L=1,R=min(l1,l2)+1;
while(L<R)
{
int mid=(L+R)/2, flag=0;
int i=1,j=1;
while(i<=n && j<=n)
{
j=i;
while(h[j+1]>=mid) ++j;
int fg1=0,fg2=0;
for(int k=i; k<=j; k++)
{
if(sa[k]<=l1) fg1=1;
if(sa[k]>l1+1) fg2=1;
}
if(fg1 && fg2) flag=1;
i=j+1;
}
if(flag) L=mid+1;
else R=mid;
}
if(L-1==0)
{
printf("0\n");
return 0;
}
int mx = n+1;
int i=1,j=1;
while(i<=n && j<=n)
{
j=i;
while(h[j+1]>=L-1) ++j;
int fg1=0,fg2=0;
for(int k=i; k<=j; k++)
{
if(sa[k]<=l1) fg1=1;
if(sa[k]>l1+1) fg2=1;
}
if(fg1 && fg2)
{
for(int k=i; k<=j; k++)
if(sa[k]>l1+1) mx=min(mx,sa[k]);
}
i=j+1;
}
for(int k=0; k<L-1; k++) printf("%c",str[mx+k]);
printf("\n%d\n",L-1);
}
[Codechef SSTORY] A Story with Strings - 后缀数组,二分的更多相关文章
- BZOJ 3230: 相似子串( RMQ + 后缀数组 + 二分 )
二分查找求出k大串, 然后正反做后缀数组, RMQ求LCP, 时间复杂度O(NlogN+logN) -------------------------------------------------- ...
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
- 【bzoj4310】跳蚤 后缀数组+二分
题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个 ...
- BZOJ 1717 [USACO06DEC] Milk Patterns (后缀数组+二分)
题目大意:求可重叠的相同子串数量至少是K的子串最长长度 洛谷传送门 依然是后缀数组+二分,先用后缀数组处理出height 每次二分出一个长度x,然后去验证,在排序的后缀串集合里,有没有连续数量多于K个 ...
- POJ 1743 [USACO5.1] Musical Theme (后缀数组+二分)
洛谷P2743传送门 题目大意:给你一个序列,求其中最长的一对相似等长子串 一对合法的相似子串被定义为: 1.任意一个子串长度都大于等于5 2.不能有重叠部分 3.其中一个子串可以在全部+/-某个值后 ...
- Poj 1743 Musical Theme(后缀数组+二分答案)
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...
- Poj 3261 Milk Patterns(后缀数组+二分答案)
Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...
- poj 2406 Power Strings (后缀数组 || KMP)
Power Strings Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 28859 Accepted: 12045 D ...
- poj 2406 Power Strings 后缀数组解法
连续重复子串问题 poj 2406 Power Strings http://poj.org/problem?id=2406 问一个串能否写成a^n次方这种形式. 虽然这题用kmp做比较合适,但是我们 ...
随机推荐
- 获取Windows平台下 安装office 版本位数信息
最近在处理客户端安装程序过程,有一个需求:需要检测Windows平台下安装office 版本信息以及获取使用的office是32 位还是64 位: 当检测出office 位数为64位时,提示当前off ...
- LNMP+HTTPS
title: "Lnmp + Https" date: 2019-08-28T16:18:20+08:00 draft: true --- 注:我的linux的ip地址为192.1 ...
- CVE-2020-1938/CNVD-2020-10487 幽灵猫漏洞
漏洞描述(后期跟进漏洞分析) Tomcat是由Apache软件基金会属下Jakarta项目开发的Servlet容器,按照Sun Microsystems提供的技术规范,实现了对Servlet和Java ...
- MySQL优化(四)——读写分离
1.MySQL高可用 主从复制 一主多备 多主多备 读写分离 减少IO开销,防止阻塞等等 2.主从复制参考 https://www.cnblo ...
- SpringBoot原理—分析SpringBoot启动机制(starter机制)
一:前言使用过springboot的同学应该已经知道,springboot通过默认配置了很多框架的使用方式帮我们大大简化了项目初始搭建以及开发过程.本文的目的就是一步步分析springboot的启动过 ...
- 在javascript编程语言中,数据类型boolean的相关知识
一. 1.字符串类型: 空字符串返回false,非空字符串均返回true; 2.数值类型: 0或NaN返回false,其他数值返回true; 3.布尔类型: false返回false,true返回tr ...
- C语言->关于文件数据的录入和输出调用的函数总结
数据输入输出对象之间的关系图: 函数使用说明: 1.一个字符的输入\输出,对象是键盘(缓存和屏幕) 1.1.getchar(a),putchar(a); 1.2.scanf(“%d”,&i), ...
- tensor数据基操----索引与切片
玩过深度学习图像处理的都知道,对于一张分辨率超大的图片,我们往往不会采取直接压平读入的方式喂入神经网络,而是将它切成一小块一小块的去读,这样的好处就是可以加快读取速度并且减少内存的占用.就拿医学图像处 ...
- Flink架构,源码及debug
序 工作中用Flink做批量和流式处理有段时间了,感觉只看Flink文档是对Flink ProgramRuntime的细节描述不是很多, 程序员还是看代码最简单和有效.所以想写点东西,记录一下,如果能 ...
- 与soul上的一个妹子聊天有感
写此篇的原因: 妹子说,我考上公务员了~,当时自己自己顿时哽咽了,不知道说什么,习惯性的说了句,恭喜恭喜啊.感受到妹子的欢喜与喜悦,我也没必要打扰她的兴致,她开心就好了嘛. 每个人的成就都是自己奋斗的 ...