BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)
求多串的最长公共字串.
法1: 二分长度+hash 传送门
法2: 二分+后缀数组 传送门
法3: 后缀自动机
拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再在全局取最小值(因为是所有串的公共串)就行了.
CODE
#include<bits/stdc++.h>
using namespace std;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &res) {
char ch; int flg = 1; while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
for(res=ch-'0';isdigit(ch=getchar());res=res*10+ch-'0'); res*=flg;
}
const int MAXN = 2005;
const int C = 26;
int m, lk[MAXN<<1], ch[MAXN<<1][C], len[MAXN<<1], mx[MAXN<<1], mn[MAXN<<1], bin[MAXN<<1], seq[MAXN<<1], sz, last;
inline void init() {
last = sz = 0; ++sz;
lk[0] = -1; len[0] = 0;
}
inline void Copy(int A, int B) {
lk[A] = lk[B];
memcpy(ch[A], ch[B], sizeof ch[B]);
}
inline int insert(int p, int c) {
int cur = sz++; last = cur;
len[cur] = len[p] + 1;
for(; ~p && !ch[p][c]; p = lk[p]) ch[p][c] = cur;
if(p == -1) lk[cur] = 0;
else {
int q = ch[p][c];
if(len[p] + 1 == len[q]) lk[cur] = q;
else {
int x = sz++;
len[x] = len[p] + 1;
Copy(x, q);
lk[cur] = lk[q] = x;
for(; ~p && ch[p][c] == q; p = lk[p]) ch[p][c] = x;
}
}
return last;
}
inline void Match(char *s) {
int p = 0, now = 0, j = 0;
for(int c; s[j]; ++j) {
if(ch[p][c=s[j]-'a'])
++now, p = ch[p][c];
else {
for(; ~p && !ch[p][c]; p = lk[p]);
if(p == -1) now = p = 0;
else now = len[p] + 1, p = ch[p][c];
}
mx[p] = max(mx[p], now);
}
for(int i = sz-1; i; --i) {
mn[seq[i]] = min(mn[seq[i]], mx[seq[i]]);
mx[lk[seq[i]]] = max(mx[lk[seq[i]]], mx[seq[i]]);
mx[seq[i]] = 0;
}
}
char s[MAXN];
int main() {
read(m); scanf("%s", s);
if(--m == 0) return printf("%d\n", strlen(s)), 0;
init(); int p = 0;
for(int i = 0; s[i]; ++i) p = insert(p, s[i]-'a');
for(int i = 0; i < sz; ++i) ++bin[mn[i] = len[i]];
for(int i = 1; i < sz; ++i) bin[i] += bin[i-1];
for(int i = sz-1; ~i; --i) seq[--bin[len[i]]] = i;
while(m--) scanf("%s", s), Match(s);
int ans = 0;
for(int i = 1; i < sz; ++i)
ans = max(ans, mn[i]);
printf("%d\n", ans);
}
BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)的更多相关文章
- BZOJ 2946: [Poi2000]公共串
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 787 Solved: 342[Submit][Status][D ...
- BZOJ 2946: [Poi2000]公共串( 后缀自动机 )
一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...
- bzoj 2946: [Poi2000]公共串【SAM】
对第一个串建SAM,把剩下的串在上面跑,每次跑一个串的时候在SAM的端点上记录匹配到这的最大长度,然后对这些串跑的结果取min,然后从这些节点的min中取max就是答案 注意在一个点更新后它的祖先也会 ...
- bzoj 2946 [Poi2000]公共串——后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2946 对每个串都建一个后缀自动机,然后 dfs 其中一个自动机,记录同步的话在别的自动机上走 ...
- BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)
题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...
- BZOJ 2946 [Poi2000]公共串 ——后缀自动机
任意选择一个串作为模式串,构建出后缀自动机. 然后用其他的串在后缀自动机上跑匹配. 然后就到了理解后缀自动机性质的时候. 在某一个节点的最大值是可以沿着parent树上传的. 然后用dp[i][j]表 ...
- 【BZOJ 2946】 2946: [Poi2000]公共串 (SAM)
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1063 Solved: 469 Description ...
- 【BZOJ】2946: [Poi2000]公共串
http://www.lydsy.com/JudgeOnline/problem.php?id=2946 题意:给n个串,求最大公共子串.(1<=n<=5,每个串长度<=2000) ...
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
随机推荐
- 基于.NET架构的树形动态报表设计与应用
在一些统计报表中,利用树形结构报表来实现维度钻取功能是十分常见的.通过逐级钻取,可以快速查看更细粒度的指标数据,如项目施工进度报告等. 使用葡萄城报表控件——ActiveReports ,即可轻松设计 ...
- JDK1.8 新特性(全)
原文链接:https://blog.csdn.net/qq_29411737/article/details/80835658
- mybatis-plus代码生成器两版(全部生成+部分生成)
mybatis-plus代码生成器两版(全部生成+部分生成) 一次性生成全部文件 package com.layuicms.erp.utils; import java.util.List; impo ...
- Java实现链队
一.分析 队列是一种先进先出的线性表,它只允许在表的一端进行插入,而在另一端删除元素.允许插入的一端称为队尾,允许删除的一端称为队头. 链队是指采用链式存储结构实现的队列,它的基本操作如下: 1.初始 ...
- VC/MFC 进程间通信方法总结
摘 要 随着人们对应用程序的要求越来越高,单进程应用在许多场合已不能满足人们的要求.编写多进程 / 多线程程序成为现代程序设计的一个重要特点,在多进程程序设计中,进程间的通信是不可避免的. M ...
- maven:无效的目标发行版:11
maven:无效的目标发行版:11 我之前在博客里是不记录bug和error的处理的,昨天听了一个资深程序员的视频,决定要改习惯了,记录一些自己平时遇到的问题 这个是我在mvn clean insta ...
- git commit报错解决,绕过代码检查
上一个项目用的svn,新项目用了git,很开心,终于学习了git了,本以为把git都学会了,但是还是遇到了一个不在自己学习的知识点范围内的问题,最后是同事帮忙解决的. 问题:第一次代码commit的时 ...
- Java高并发程序设计学习笔记(八):NIO和AIO
转自:https://blog.csdn.net/dataiyangu/article/details/87214773 什么是NIOBuffer && ChannelBuffer举个 ...
- 【Swift后台】背景介绍
在2017年11月的时候,就已经对Swift后台进行过研究,简书上发表过相应文章,那时候发表的是单纯的对Vapor文档的翻译,此次则是作为进一步研究的学习笔记来保存. Swift后台的本质,主要是Va ...
- windows下修改vagrant虚拟机中的html ,通过nginx访问后不生效
更改本地html文件,通过nginx配置的虚拟域名访问, 无论怎么修改内容,都不变化,即使我把内容删除一半,它显示的也是以前内容的一半,除非删除文件,才会从新生成. 解决办法 修改nginx.conf ...