题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6138

题意:给n个串,每次询问x号串和y号串的最长公共子串的长度,这个子串必须是n个串中某个串的前缀

解法1:AC自动机。做法是把n个串建成AC自动机,前缀树中每个节点都当做结尾节点,val赋为trie树深度,然后把x串丢进自动机里,把匹配到的前缀节点染个色,再把y串丢进去,遇到同样颜色的前缀节点就更新一下答案。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int M = 5e5+10;
const int S = 26;
struct AcAutomata{
int root,sz;
int nxt[M][S],fail[M],val[M],col[N];
int newnode(){
val[sz] = col[sz] = 0;
memset(nxt[sz], -1, sizeof(nxt[sz]));
return sz++;
}
void init(){
memset(val, 0, sizeof(val));
sz = 0;
root = newnode();
}
void insert(char *s){
int u=root;
int len=strlen(s);
for(int i=0; i<len; i++){
int id=s[i]-'a';
if(nxt[u][id]==-1) nxt[u][id]=newnode();
val[nxt[u][id]]=val[u]+1;
u=nxt[u][id];
}
}
void build(){
queue <int> q;
fail[root] = root;
for(int i=0; i<S; i++){
int &v = nxt[root][i];
if(~v){
fail[v] = root;
q.push(v);
}
else{
v = root;
}
}
while(q.size()){
int u = q.front(); q.pop();
for(int i = 0; i < S; i++){
int &v = nxt[u][i];
if(~v){
fail[v] = nxt[fail[u]][i];
q.push(v);
}
else{
v = nxt[fail[u]][i];
}
}
}
}
void update(char *s, int x){
int len = strlen(s);
int u=root;
for(int i=0; i<len; i++){
int id=s[i]-'a';
u=nxt[u][id];
int tmp=u;
while(tmp){
col[tmp]=x;
tmp=fail[tmp];
}
}
}
int query(char *s, int x){
int len = strlen(s);
int u = root;
int ans = 0;
for(int i=0; i<len; i++){
int id=s[i]-'a';
u=nxt[u][id];
int tmp=u;
while(tmp){
if(col[tmp]==x) ans=max(ans, val[tmp]);
tmp=fail[tmp];
}
}
return ans;
}
}ZXY;
char s[N];
int pos[N];
int main()
{
int T,n,q;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
ZXY.init();
int d=1;
for(int i=1; i<=n; i++){
pos[i]=d;
scanf("%s", s+d);
ZXY.insert(s+d);
int len=strlen(s+d);
d+=len+1;
}
ZXY.build();
scanf("%d", &q);
int id=1;
while(q--)
{
int x, y;
scanf("%d%d",&x,&y);
ZXY.update(s+pos[x],id);
int ans = ZXY.query(s+pos[y],id);
++id;
printf("%d\n", ans);
}
}
return 0;
}

解法2:KMP,直接枚举n个串做KMP。。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
vector<int> Next[maxn];
string str[maxn];
void getnext(string &s, vector<int> &nxt)
{
int len = s.size();
nxt.resize(len);
nxt[0] = -1;
int i, j = -1;
for(i = 1; i < len; i++)
{
while(j >= 0 && s[j + 1] != s[i])
j = nxt[j];
if(s[j + 1] == s[i])
j++;
nxt[i] = j;
}
}
int getMax(string &s, int strid)
{
int len = s.size();
int i, j = -1;
int ret = 0;
for(i = 0; i < len; i++)
{
while(j >= 0 && str[strid][j + 1] != s[i])
j = Next[strid][j];
if(str[strid][j + 1] == s[i])
j++;
ret = max(ret, j + 1);
}
return ret;
}
char buf[maxn];
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%s", buf);
str[i] = buf;
getnext(str[i], Next[i]);
}
int q;
scanf("%d", &q);
while(q--)
{
int x, y;
scanf("%d %d", &x, &y);
int ans = 0;
for(int i = 1; i <= n; i++)
{
int u = getMax(str[x], i);
int v = getMax(str[y], i);
ans = max(ans, min(u, v));
}
printf("%d\n", ans);
}
}
return 0;
}

2017多校第8场 HDU 6138 Fleet of the Eternal Throne AC自动机或者KMP的更多相关文章

  1. 2017多校第8场 HDU 6138 Fleet of the Eternal Throne 思维,暴力

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6138 题意:给了初始区间[-1,1],然后有一些操作,可以r加上一个数,l减掉一个数,或者同时操作,问 ...

  2. HDU 6138 Fleet of the Eternal Throne(后缀自动机)

    题意 题目链接 Sol 真是狗血,被疯狂卡常的原因竟是 我们考虑暴力枚举每个串的前缀,看他能在\(x, y\)的后缀自动机中走多少步,对两者取个min即可 复杂度\(O(T 10^5 M)\)(好假啊 ...

  3. HDU 6138 Fleet of the Eternal Throne(AC自动机)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6138 [题目大意] 给出一些串,询问第x个串和第y个串的公共子串, 同时要求该公共子串为某个串的前 ...

  4. 2017ACM暑期多校联合训练 - Team 8 1006 HDU 6138 Fleet of the Eternal Throne (字符串处理 AC自动机)

    题目链接 Problem Description The Eternal Fleet was built many centuries ago before the time of Valkorion ...

  5. HDU 6138 Fleet of the Eternal Throne 后缀数组 + 二分

    Fleet of the Eternal Throne Problem Description > The Eternal Fleet was built many centuries ago ...

  6. 2017多校第6场 HDU 6096 String AC自动机

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6096 题意:给了一些模式串,然后再给出一些文本串的不想交的前后缀,问文本串在模式串的出现次数. 解法: ...

  7. 2017多校第9场 HDU 6170 Two strings DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6170 题意:给了2个字符串,其中第2个字符串包含.和*两种特别字符,问第二个字符串能否和第一个匹配. ...

  8. 2017多校第9场 HDU 6161 Big binary tree 思维,类似字典树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6161 题意: 题目是给一棵完全二叉树,从上到下从左到右给每个节点标号,每个点有权值,初始权值为其标号, ...

  9. 2017多校第9场 HDU 6169 Senior PanⅡ 数论,DP,爆搜

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6169 题意:给了区间L,R,求[L,R]区间所有满足其最小质数因子为k的数的和. 解法: 我看了这篇b ...

随机推荐

  1. Oracle 物化视图创建以及常见问题

    create materialized view MV_XXXXrefresh fast on commitwith rowidenable query rewriteasselect * from ...

  2. Codeforces 864E Fire(背包DP)

    背包DP,决策的时候记一下 jc[i][j]=1 表示第i个物品容量为j的时候要选,输出方案的时候倒推就好了 #include<iostream> #include<cstdlib& ...

  3. IE的CSS渲染跟其它浏览器有什么不同

    由于IE系浏览器对标准的支持不够好,导致Web开发中经常需要去处理浏览器兼容性问题,特别有些莫名其妙的问题很让人头疼,今天要说这个问题就是这样的,先从插入CSS的三种方法说起: 外部样式(Extern ...

  4. 如何在Linux上安装QQ

    我一直无法解决Ubuntu QQ问题,而最近我重装ubuntu之后在网络上找到与QQ相关的内容,网上有大神开发出了新版的wineQQ,解决了我们对QQ的需求.经过尝试,完成了QQ安装 如图  安装的是 ...

  5. radio is checked

    var is_rec =$("#is_rec_on").is(':checked'); if(is_rec){ $('.rec_img').css('display','block ...

  6. c# 折半查找法实现代码

    ] { , , , , , , , , , , , , , , , , , , , }; , i; string j, k; , ); ) { k = String.Format("未找到{ ...

  7. Intellij IDEA 使用jrebel运行spring-boot并实现自动编译进行热部署

    在使用jrebel运行spring-boot的时候,会发现一个很棘手的问题,就是项目不能自动编译,不能自动编译就不能实现热部署.(使用jar包方式运行的时候) 那么我们就要解决自动编译的问题,首先: ...

  8. [LeetCode] 18. 4Sum ☆☆

    Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...

  9. MongoDB入门(1)- MongoDB简介

    什么是MongoDB NoSQL NoSQL systems are also sometimes called "Not only SQL" to emphasize that ...

  10. mysql 压缩包免安装版 安转步骤

    一. 下载 MySQL 的官网下载地址:http://www.mysql.com/downloads/ 在这个下载界面会有几个版本的选择. 1. MySQL Community Server 社区版本 ...