SPOJ_LCS2
和上个题目差不多,这次是找若干个串的LCS,若干<=10 。
做法上面也是类似的。
首先以第一个建立SAM,然后后面的串都在上面更新。每个串的更新是独立进行的,互不影响。对于同一状态,首先在同一个串的更新中取最大值,然后再不同的串之间取最小值,最后统计一下所有状态的最大值就可以了。
与上面不同的是,多了一个小小的操作,对于某一个状态存在一个匹配长度x,那么在该状态上所有的pre指针所指向的状态的的匹配长度都肯定会是step值。
一开始我也不理解为什么,后来发现后缀自动机的性质啦嘿嘿,(想一想就知道咯)。
但是为什么不更新pre指针会错呢?其实是这样的,每次加入一个字符匹配,当前只可能在一个状态,但是其实pre指针所有的位置都是可以进行匹配的。而且由于串很多,所有后面的串不一定都更新在这个状态,虽然他们的right位置是一样的。。(嗯,好像很有道理)
为什么上一个题目lcs没有对pre指针进行更新却依然正确呢?原因是不需要,对于每个状态step相当于与第一个模式串比配的最大长度,注意是最大,所以在第二个字符串来匹配的时候,当前状态的长度就是两个串在该状态的最大公共长度了。同时,在该状态的所有pre状态也肯定会存在匹配长复,但是那些肯定都不会优于这个状态,所以这个更新是不必要的,而对于多个串,由于每个串在可能分别落在不同的pre指针上,所以需要跟新一遍咯。
召唤代码君:
#include <iostream>
#include <cstdio>
#define maxn 200100
using namespace std; int next[maxn][26],pre[maxn],step[maxn];
int f[13][maxn];
int N=0,last=0,n=1;
int p,q,np,nq;
char s[13][maxn]; void insert(int x,int m)
{
np=++N,p=last,step[np]=m;
while (p!=-1 && next[p][x]==0) next[p][x]=np,p=pre[p];
last=np;
if (p==-1) return;
q=next[p][x];
if (step[q]==step[p]+1) { pre[np]=q; return ; }
nq=++N,step[nq]=step[p]+1,pre[nq]=pre[q];
for (int i=0; i<26; i++) next[nq][i]=next[q][i];
pre[np]=pre[q]=nq;
for (; p!=-1 && next[p][x]==q;p=pre[p]) next[p][x]=nq;
} void dp(int x)
{
int cur=0,tmp=0;
for (int i=0; s[x][i]; i++)
{
int k=s[x][i]-'a';
while (next[cur][k]==0 && cur!=0) cur=pre[cur];
tmp=min(step[cur],tmp);
cur=next[cur][k];
if (cur) tmp++;
f[x][cur]=max(f[x][cur],tmp);
}
for (int i=N; i>0; i--)
if (f[x][i])
for (int j=pre[i];j && f[x][j]!=step[j];j=pre[j]) f[x][j]=step[j];
} int main()
{
pre[0]=-1;
while (scanf("%s",s[n])!=EOF) n++; n--;
for (int i=0; s[1][i]; i++) insert(s[1][i]-'a',i+1);
for (int i=2; i<=n; i++) dp(i);
int ans=0;
for (int i=1; i<=N; i++)
{
int tmp=step[i];
for (int j=2; j<=n; j++) tmp=min(tmp,f[j][i]);
ans=max(ans,tmp);
}
printf("%d\n",ans);
return 0;
}
SPOJ_LCS2的更多相关文章
随机推荐
- python爬虫之Scrapy框架(CrawlSpider)
提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬去进行实现的(Request模块回调) 方法二:基于CrawlSpi ...
- 由 Session 和 Cookie 的区别说起
Session 和 Cookie 有什么区别? 最近面试被问到这个问题,和面试官一番讨论了解到面试官心里的答案后,我不太满意. 面对上面的问题,如果是刚毕业时的我,一定会毫不犹豫说出 Cookie 是 ...
- 我们一起来聊聊并发吧,one。
引言 最近工作当中写了一个有关并发的程序,引起了LZ对并发的强烈兴趣.这一下一发不可收拾,LZ用了一个多星期,看完了这本共280+页的并发编程书.之所以能看这么快,其实这主要归功于,自己之前对并发就有 ...
- python解释 yield 和 Generators(生成器)
yield 和 Generators(生成器) 转自:http://www.oschina.net/translate/improve-your-python-yield-and-generators ...
- scrapy的简单使用
使用之前的创建虚拟环境方法(pipenv) 创建虚拟环境并进入虚拟环境 mkdir douban cd douban pipenv install pipenv shell 再安装我们的scrapy ...
- Redis的C语言客户端(hiredis)的安装和使用
关键词:hiredis, cRedis, redis clients, redis客户端, C客户端, 华为云分布式缓存服务 hiredis是一个非常全面的C语言版redis接口库,支持所有命令.管道 ...
- RabbitMQ和Kafka,更加便捷高效的消息队列使用方式,请放心食用
一.RabbitMQ实例介绍RabbitMQ实例由华为云分布式消息服务(DMS)团队打造,实例采用物理隔离的方式部署,租户独占RabbitMQ实例.一键式部署,完全兼容开源RabbitMQ的使用方式, ...
- 【视频编解码·学习笔记】13. 提取PPS信息程序
PPS结构解析 与之前解析SPS方式类似 一.定义PPS类: 在3.NAL Unit目录下,新建PicParamSet.cpp和PicParamSet.h,在这两个文件中写入类的定义和函数实现. 类定 ...
- 用Solidity在Truffle上构建一个HelloWorld智能合约
原文地址:石匠的blog Truffle的环境安装在前文已经整理,这次用Solidity在Truffle写一个HelloWorld以太坊智能合约,并在testrpc上进行测试.当前的软件版本信息如下: ...
- Laravel路由除了根目录全报404错误
Route::get('hello',function(){ return 'Hello World!'; }); 在laravel/app/Http/routes.php下添加上面的语句,然后再浏览 ...