[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 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们 ...
随机推荐
- [转]softmax函数详解
答案来自专栏:机器学习算法与自然语言处理 详解softmax函数以及相关求导过程 这几天学习了一下softmax激活函数,以及它的梯度求导过程,整理一下便于分享和交流. softmax函数 softm ...
- MySQL修改datadir目录
更改MySQL的数据目录由/usr/local/mysql/data/更换至/data/mysql/ 第一种方法修改my.cnf 1)关闭MySQL [root@test2 ~]# service m ...
- mycat读写分离与主从切换【转】
什么是mycat,以及mycat的优点和特性本文不做赘述,本文继续本着实战的态度,来分享一些个人对mycat的基础功能实践.本文mycat的读写分离和主从切换的环境为mysql主从环境. 如何安装my ...
- tf.summary.merge_all()
1.自动管理模式 summary_writer = tf.summary.FileWriter('E:/data/tensorflow-master/1.Cnn_Captcha/result/', f ...
- excl筛选求和
Excel中的筛选,是一个很常用的功能.但不知道是有意还是疏忽,Excel没有直接提供在筛选后的一些统计功能,例如求和.平均值等.而由于筛选的主要功能之一就是可以方便快捷的进行变换,所普通的以直接在数 ...
- sql server 2000系统表sysproperties在SQL 2008中无效的问题
Sqlserver有一个扩展属性系统表sysproperties,因为只接触过MSSQL2005及以后的版本,在生产库2008版本及联机文档上搜了下都找不到这个系统表,后来发现这个系统表在2005版本 ...
- SQL农历转换函数(显示中文格式,加入润月的显示)
if object_id('fn_getlunar') is not null drop function fn_getlunar go create function dbo.fn_getlunar ...
- sql查询与修改数据库逻辑文件名,移动数据库存储路径
USE mydb GO --1.查询当前数据库的逻辑文件名 ) ) AS 'File Name 2'; --或通过以下语句查询: --SELECT name FROM sys.database_fil ...
- iOS图片缓存
iOS的内存管理始终是开发者面临的大问题,内存占用过大时,很容易会被系统kill掉,开发者需要尽可能的优化内存占用问题. 现在的App界面做的越来越精致,里面集成了大量的图片,笔者首先想到的就是如何减 ...
- hdu 3951 硬币围成一圈(博弈)
n个硬币围成一个环 每次只能取1-K个硬币 最后取完者胜 假如5个硬币 每次取1-2个情况1 先手取1个 后手取剩下4个中间2个 破坏了连续 虽然最后剩2个,但先手只能取一个 然后后再取一个 后手胜 ...