[POI2000]Repetitions
题目大意:
求多个字符串的LCS。
思路:
同SPOJ-LCS2,不过因为SPOJ上数据比较水,当时用错误的写法过掉了,这次用正确的写法重新过了一遍。
拓扑排序按照每个状态的len值,用计数排序实现。
每个状态往上更新时,应该对std::min(s[p].maxlen,s[q].len)取max(每个状态能匹配的最长子串长度不超过len)。
#include<cstdio>
#include<cstring>
#include<algorithm>
const int inf=0x7fffffff;
const int LEN=;
int n;
char s[LEN];
class SuffixAutomaton {
private:
static const int SIGMA_SIZE=;
struct State {
int len,link,go[SIGMA_SIZE],maxlen,min;
};
int sz,root,last,len;
int cnt[LEN],top[LEN<<];
State s[LEN<<];
int newState(const int l) {
sz++;
s[sz].len=l;
s[sz].min=inf;
return sz;
}
int idx(const char ch) {
return ch-'a';
}
void extend(const char ch) {
int w=idx(ch);
int p=last;
int new_p=newState(s[p].len+);
while(p&&!s[p].go[w]) {
s[p].go[w]=new_p;
p=s[p].link;
}
if(!p) {
s[new_p].link=root;
s[root].go[w]=new_p;
} else {
int q=s[p].go[w];
if(s[q].len==s[p].len+) {
s[new_p].link=q;
} else {
int new_q=newState(s[p].len+);
memcpy(s[new_q].go,s[q].go,sizeof s[q].go);
s[new_q].link=s[q].link;
s[q].link=s[new_p].link=new_q;
while(p&&s[p].go[w]==q) {
s[p].go[w]=new_q;
p=s[p].link;
}
}
}
last=new_p;
}
public:
void build(char str[]) {
root=last=newState();
len=strlen(str);
for(int i=;str[i];i++) extend(str[i]);
}
void top_sort() {
for(int i=;i<=sz;i++) cnt[s[i].len]++;
for(int i=len;i;i--) cnt[i-]+=cnt[i];
for(int i=;i<=sz;i++) top[cnt[s[i].len]--]=i;
}
void match(char str[]) {
int p=root,tmp=;
for(int i=;str[i];i++) {
int w=idx(str[i]);
if(s[p].go[w]) {
tmp++;
p=s[p].go[w];
} else {
while(p&&!s[p].go[w]) {
p=s[p].link;
}
if(!p) {
tmp=;
p=root;
} else {
tmp=s[p].len+;
p=s[p].go[w];
}
}
s[p].maxlen=std::max(s[p].maxlen,tmp);
}
for(int i=;i<=sz;i++) {
int p=top[i],q=s[p].link;
s[q].maxlen=std::max(s[q].maxlen,std::min(s[p].maxlen,s[q].len));
s[p].min=std::min(s[p].min,s[p].maxlen);
s[p].maxlen=;
}
}
int lcs() {
int ret=;
for(int i=;i<=sz;i++) ret=std::max(ret,s[i].min);
return ret;
}
};
SuffixAutomaton sam;
int main() {
scanf("%d",&n);
scanf("%s",s);
sam.build(s);
sam.top_sort();
for(int i=;i<=n;i++) {
scanf("%s",s);
sam.match(s);
}
printf("%d\n",sam.lcs());
return ;
}
[POI2000]Repetitions的更多相关文章
- BZOJ 2946: [Poi2000]公共串
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 787 Solved: 342[Submit][Status][D ...
- 【BZOJ】【2938】【POI2000】病毒
AC自动机 好题>_<(其实是一次AC有些感动) 嗯要找到无限长的一个字符串不包含任何一个模板串,就意味着在AC自动机(Trie图)上找到一个不经过任何一个危险结点的环,深搜一下就好了…… ...
- bzoj2940: [Poi2000]条纹
2940: [Poi2000]条纹 条纹游戏是一个双人的游戏.所需要的物品有一个棋盘以及三种颜色的长方形条纹,这三种颜色分别是红色.绿色和蓝色.所有的红色条纹的尺寸是c*1,所有的绿色条纹的尺寸是z* ...
- BZOJ 2946: [Poi2000]公共串( 后缀自动机 )
一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...
- HUST 1352 Repetitions of Substrings(字符串)
Repetitions of Substrings Description The “repetitions” of a string S(whose length is n) is a maximu ...
- CJOJ 2482 【POI2000】促销活动
CJOJ 2482 [POI2000]促销活动(STL优先队列,大根堆,小根堆) Description 促销活动遵守以下规则: 一个消费者 -- 想参加促销活动的消费者,在账单下记下他自己所付的费用 ...
- BZOJ 2938: [Poi2000]病毒 [AC自动机 拓扑排序]
2938: [Poi2000]病毒 题意:判断是否存在无限长的不含模式串的字符串.只有01. 建出套路DP的转移图,判断有环就行了 练习一下拓扑排序 #include <iostream> ...
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
- BZOJ_2938_[Poi2000]病毒_AC自动机
BZOJ_2938_[Poi2000]病毒_AC自动机 Description 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们 ...
随机推荐
- IE的双边距Bug以及解决办法
display:inline和display:block区别 一.什么是双边距Bug? 先来看图: 我们要让绿色盒模型在蓝色盒模型之内向左浮动,并且距蓝色盒模型左侧100像素.这个例子很常见,比如在网 ...
- java map遍历并删除特定值
删除map中包含password和username的键值对 若是在map中直接删除,会指针错误 Iterator<Map.Entry<String,Object>> it = ...
- Gitlab权限管理
使用管理员登陆gitlab(版本为8.9)创建一个组 给用户授权 创建新用户 再创建两个dev1和dev2 然后再到项目界面授权给pm授权master 创建库(事先先建一个java组) 设置权限 创建 ...
- 11 The Go Memory Model go语言内置模型
The Go Memory Model go语言内置模型 Version of May 31, 2014 Introduction 介绍 Advice 建议 Happens Before 在发生之前 ...
- 洛谷P3088 挤奶牛
传送门啦 这个题也是一个单调队列来优化的 $ dp $ ,我们考虑这个题,这个题让我们求出有多少奶牛会觉得拥挤,如果我们还像琪露诺那个题那样单纯用一次单调队列肯定是不行的,因为牛觉不觉得拥挤是受左右的 ...
- Linux学习笔记:touch新建文件、修改访问、改动时间
touch用于创建新的空文件或者修改已有文件的时间戳. 语法:touch file.txt 如果file存在,使用touch指令可更改这个文件或目录的日期时间,包括存取时间和更改时间. 如果file不 ...
- 通过构造系统服务分发实现拦截&过滤 (仿360游戏保险箱)
想写这个程序主要是因为看了KSSD的一篇帖子,http://bbs.pediy.com/showthread.php?t=108378 讲 的是360保险箱保护游戏账号的原理,实际上就是对各种请求的拦 ...
- BZOJ囤题计划
决定做一些题,学习jry,开坑(其实是填坑) 大概会刷的很慢,大家别鄙视我..欢迎鄙视 果然慢出翔了,还是填完吧.. 现在做了: 11 [2338][HNOI2011]数矩形 枚举对角线暴力水过,所有 ...
- IDEA创建Spring Boot项目
首先安装Spring Boot CLI 先确定自己安装的JDK是1.8版本或者以上,然后下载Srping Boot CLI,Spring Boot CLI下载地址,下载下来是一个压缩包,解压,得到一个 ...
- MapReduce的原理及执行过程
MapReduce简介 MapReduce是一种分布式计算模型,是Google提出的,主要用于搜索领域,解决海量数据的计算问题. MR有两个阶段组成:Map和Reduce,用户只需实现map()和re ...