[POI2000] 公共串 - 后缀数组,二分

时间:2022-08-27 15:02:32

[POI2000] 公共串

Description

给出几个由小写字母构成的单词,求它们最长的公共子串的长度。

Solution

预处理出后缀数组和高度数组,二分答案 \(k\) ,对于每一个连续的 \(RMQ\) 大于等于 \(k\) 的段,判断其中是否有来源于每一个串的后缀即可。

#include <bits/stdc++.h>
using namespace std; int n,m=256,sa[1000005],y[1000005],u[1000005],v[1000005],o[1000005],r[1000005],h[1000005],T;
// sa: Suffix Array
// r: Rank Array
// h: Height Array (between sa[i] & sa[i-1])
char str[1000005];
long long ans;
int bel[1000005];
int buf[10]; int main()
{
string s[6];
int T;
cin>>T;
for(int i=1; i<=T; i++) cin>>s[i]; int pin=0;
for(int i=1; i<=T; i++)
{
for(int j=1; j<=s[i].length(); j++)
str[pin+j]=s[i][j-1],
bel[pin+j]=i;
str[pin+s[i].length()+1]='z'+(char)i;
pin+=s[i].length()+1;
}
n=strlen(str+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=1e+9;
for(int i=1; i<=T; i++) r=min(r,(int)s[i].length());
++r;
while(l<r)
{
int mid = (l+r)/2;
int i=1,j=1,flag=0;
while(i<=n && j<=n)
{
j=i;
while(h[j+1]>=mid) ++j;
for(int k=1; k<=T; k++) buf[k]=0;
for(int k=i; k<=j; k++) buf[bel[sa[k]]]=1;
int fg=1;
for(int k=1; k<=T; k++) if(buf[k]==0) fg=0;
if(fg) flag = 1;
i=j+1;
}
if(flag) l=mid+1;
else r=mid;
}
cout<<l-1<<endl;
} }

[POI2000] 公共串 - 后缀数组,二分的更多相关文章

  1. 【BZOJ2946】&lbrack;Poi2000&rsqb;公共串 后缀数组&plus;二分

    [BZOJ2946][Poi2000]公共串 Description        给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单词 l        计 ...

  2. BZOJ 2946&colon; &lbrack;Poi2000&rsqb;公共串&lpar; 后缀自动机 &rpar;

    一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...

  3. 【bzoj2946】&lbrack;Poi2000&rsqb;公共串 后缀自动机

    [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1386  Solved: 620[Submit][Status][Discus ...

  4. bzoj3277 串 &lpar;后缀数组&plus;二分答案&plus;ST表&rpar;

    常见操作:先把所有串都连到一起,但中间加上一个特殊的符号(不能在原串中/出现过)作为分割 由于全部的子串就等于所有后缀的所有前缀,那我们对于每一个后缀,去求一个最长的前缀,来满足这个前缀在至少K个原串 ...

  5. BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)

    题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...

  6. &lbrack;BZOJ3277&sol;BZOJ3473&rsqb; 串 - 后缀数组&comma;二分&comma;双指针&comma;ST表&comma;均摊分析

    [BZOJ3277] 串 Description 现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Solution 首先将所有串连 ...

  7. BZOJ2946 &lbrack;Poi2000&rsqb;公共串&lpar;后缀自动机&rpar;

    Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单词 l        计算最长公共子串的长度 l        输 ...

  8. bzoj 2946 &lbrack;Poi2000&rsqb;公共串——后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2946 对每个串都建一个后缀自动机,然后 dfs 其中一个自动机,记录同步的话在别的自动机上走 ...

  9. BZOJ 2946 &lbrack;Poi2000&rsqb;公共串 ——后缀自动机

    任意选择一个串作为模式串,构建出后缀自动机. 然后用其他的串在后缀自动机上跑匹配. 然后就到了理解后缀自动机性质的时候. 在某一个节点的最大值是可以沿着parent树上传的. 然后用dp[i][j]表 ...

随机推荐

  1. 运用webkit绘制渲染页面原理解决iscroll4闪动的问题

    原:http://www.iunbug.com/archives/2012/09/19/411.html 已经有不少前端同行抱怨iScroll4的各种问题,我个人并不赞同将这些问题归咎于iScroll ...

  2. POJ2425 A Chess Game&lbrack;博弈论 SG函数&rsqb;

    A Chess Game Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 3917   Accepted: 1596 Desc ...

  3. 修改Windows硬盘分区名称

    本文由 www.169it.com 收集整理 如果用户在将 XP 重装成Win7/Win8时,原本的硬盘分区名称可能会出现无法更改的情况,重新命名也都起不了作用.这种情况一般是因为使用 XP 系统下 ...

  4. MySQL优化四(优化表结构)

    body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-top: 10 ...

  5. Javascript的那些硬骨头:作用域、回调、闭包、异步……

    终于到了神话破灭的时刻-- 这注定是一篇"自取其辱"的博客,飞哥,你们眼中的大神,Duang,这次脸朝下摔地上了. 故事得从这个求助开始:e.returnValue 报错:未定义, ...

  6. Redis Cluster集群主从方案

    本文介绍一种通过Jedis和Cluster实现Redis集群(主从)的高可用方案,该方案需要使用Jedis2.8.0(推荐),Redis3.0及以上版本(强制). 附:Redis Cluster集群主 ...

  7. lvs UDP端口负载均衡配置

    ! Configuration File for keepalived global_defs { notification_email { test@163.com } notification_e ...

  8. English trip M1 - PC6 Likes and Dislike Teacher&colon;Jade

    In this lesson you will learn to talk about likes and dislikes. 课上内容(Lesson) # 通常在习惯性的表达式用 it's 来表达w ...

  9. JAVA generic array 泛型数组

    在JAVA中是不支持泛型数组的,不能通过 Z[] array=new Z[10] 这样的方式来创建数组,而是使用反射Aarry.newInstance来创建: 具体代码如下: public Z[][] ...

  10. LeetCode 6罗马数字转整数

    罗马数字包含以下七种字符:I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并列 ...