题目大意:
  求多个字符串的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的更多相关文章

  1. BZOJ 2946: [Poi2000]公共串

    2946: [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 342[Submit][Status][D ...

  2. 【BZOJ】【2938】【POI2000】病毒

    AC自动机 好题>_<(其实是一次AC有些感动) 嗯要找到无限长的一个字符串不包含任何一个模板串,就意味着在AC自动机(Trie图)上找到一个不经过任何一个危险结点的环,深搜一下就好了…… ...

  3. bzoj2940: [Poi2000]条纹

    2940: [Poi2000]条纹 条纹游戏是一个双人的游戏.所需要的物品有一个棋盘以及三种颜色的长方形条纹,这三种颜色分别是红色.绿色和蓝色.所有的红色条纹的尺寸是c*1,所有的绿色条纹的尺寸是z* ...

  4. BZOJ 2946: [Poi2000]公共串( 后缀自动机 )

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

  5. HUST 1352 Repetitions of Substrings(字符串)

    Repetitions of Substrings Description The “repetitions” of a string S(whose length is n) is a maximu ...

  6. CJOJ 2482 【POI2000】促销活动

    CJOJ 2482 [POI2000]促销活动(STL优先队列,大根堆,小根堆) Description 促销活动遵守以下规则: 一个消费者 -- 想参加促销活动的消费者,在账单下记下他自己所付的费用 ...

  7. BZOJ 2938: [Poi2000]病毒 [AC自动机 拓扑排序]

    2938: [Poi2000]病毒 题意:判断是否存在无限长的不含模式串的字符串.只有01. 建出套路DP的转移图,判断有环就行了 练习一下拓扑排序 #include <iostream> ...

  8. BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案

    BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单 ...

  9. BZOJ_2938_[Poi2000]病毒_AC自动机

    BZOJ_2938_[Poi2000]病毒_AC自动机 Description 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们 ...

随机推荐

  1. IE的双边距Bug以及解决办法

    display:inline和display:block区别 一.什么是双边距Bug? 先来看图: 我们要让绿色盒模型在蓝色盒模型之内向左浮动,并且距蓝色盒模型左侧100像素.这个例子很常见,比如在网 ...

  2. java map遍历并删除特定值

    删除map中包含password和username的键值对 若是在map中直接删除,会指针错误 Iterator<Map.Entry<String,Object>> it = ...

  3. Gitlab权限管理

    使用管理员登陆gitlab(版本为8.9)创建一个组 给用户授权 创建新用户 再创建两个dev1和dev2 然后再到项目界面授权给pm授权master 创建库(事先先建一个java组) 设置权限 创建 ...

  4. 11 The Go Memory Model go语言内置模型

    The Go Memory Model go语言内置模型 Version of May 31, 2014 Introduction 介绍 Advice 建议 Happens Before 在发生之前 ...

  5. 洛谷P3088 挤奶牛

    传送门啦 这个题也是一个单调队列来优化的 $ dp $ ,我们考虑这个题,这个题让我们求出有多少奶牛会觉得拥挤,如果我们还像琪露诺那个题那样单纯用一次单调队列肯定是不行的,因为牛觉不觉得拥挤是受左右的 ...

  6. Linux学习笔记:touch新建文件、修改访问、改动时间

    touch用于创建新的空文件或者修改已有文件的时间戳. 语法:touch file.txt 如果file存在,使用touch指令可更改这个文件或目录的日期时间,包括存取时间和更改时间. 如果file不 ...

  7. 通过构造系统服务分发实现拦截&过滤 (仿360游戏保险箱)

    想写这个程序主要是因为看了KSSD的一篇帖子,http://bbs.pediy.com/showthread.php?t=108378 讲 的是360保险箱保护游戏账号的原理,实际上就是对各种请求的拦 ...

  8. BZOJ囤题计划

    决定做一些题,学习jry,开坑(其实是填坑) 大概会刷的很慢,大家别鄙视我..欢迎鄙视 果然慢出翔了,还是填完吧.. 现在做了: 11 [2338][HNOI2011]数矩形 枚举对角线暴力水过,所有 ...

  9. IDEA创建Spring Boot项目

    首先安装Spring Boot CLI 先确定自己安装的JDK是1.8版本或者以上,然后下载Srping Boot CLI,Spring Boot CLI下载地址,下载下来是一个压缩包,解压,得到一个 ...

  10. MapReduce的原理及执行过程

    MapReduce简介 MapReduce是一种分布式计算模型,是Google提出的,主要用于搜索领域,解决海量数据的计算问题. MR有两个阶段组成:Map和Reduce,用户只需实现map()和re ...