Fleet of the Eternal Throne HDU6138

不知道为什么今天晚上神经病,一直睡不着,挣扎了四个多小时,还是决定起来搞点东西,就补了一题:A了之后对比了一下标程似乎更优化~~~快了6倍多代码也很短~

思路:对所有子串建立AC自动机,然后只需要定义两个数组,一个是每个节点的父亲,一个是每组字符串的最后一个字符的节点标号,然后就顺着每一个x串的fail指针去标记一下,然后顺着y串的fail去搜,搜到标记过的,就更新一下当前最大就好,然后就是结果了,复杂度O(n);

代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=1e5+10;
struct Trie
{
    int next[maxn][26],fail[maxn],f[maxn],dep[maxn],pos[maxn];
    bool vis[maxn];
    int root,L;
    int newnode()
    {
        for(int i = 0;i < 26;i++)
            next[L][i] = -1;
        L++;
        return L-1;
    }
    void init()
    {
        L = 0;
        dep[0]=0;
        f[0]=0;
        root = newnode();
    }
    void insert(char buf[],int k)
    {
        int len = strlen(buf);
        int now = root;
        for(int i = 0;i < len;i++)
        {
            if(next[now][buf[i]-‘a‘] == -1)
            {
                next[now][buf[i]-‘a‘] = newnode();
                dep[next[now][buf[i]-‘a‘]]=dep[now]+1;
                f[next[now][buf[i]-‘a‘]]=now;
            }
            now = next[now][buf[i]-‘a‘];
        }
        pos[k]=now;
    }
    void build()
    {
        queue<int>q;
        fail[0] = 0;
        for(int i = 0;i < 26;i++)
            if(next[0][i] == -1)
                next[0][i] = 0;
            else
            {
                fail[next[0][i]] = 0;
                q.push(next[0][i]);
            }
        while(!q.empty())
        {
            int now = q.front();q.pop();
            for(int i = 0;i < 26;i++)
            {
                int u=next[now][i];
                if(u == -1)
                    next[now][i] = next[fail[now]][i];
                else
                {
                    fail[u]=next[fail[now]][i];
                    q.push(u);
                }
            }
        }
    }
    int check(int x,int y)
    {
        memset(vis,0,(L+10)*sizeof (bool));
        for(int i=pos[x];i!=0;i=f[i])
            for(int p=i;p!=0;p=fail[p])
                vis[p]=1;
        int M=0;
        for(int i=pos[y];i!=0;i=f[i])
            for(int p=i;p!=0;p=fail[p])
                if(vis[p])M=max(M,dep[p]);
        return M;
    }
};
char buf[100005];
Trie ac;
int main()
{
    freopen("input.txt","r",stdin);
    int T,n,m;
    scanf("%d",&T);
    while( T-- )
    {
        scanf("%d",&n);
        ac.init();
        for(int i = 1;i <= n;i++)
        {
            scanf("%s",buf);
            ac.insert(buf,i);
        }
        ac.build();
        scanf("%d",&m);
        while(m--)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%d\n",ac.check(x,y));
        }
    }
    return 0;
}
时间: 2024-08-13 19:32:06

Fleet of the Eternal Throne HDU6138的相关文章

2017多校第8场 HDU 6138 Fleet of the Eternal Throne AC自动机或者KMP

题目链接: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 s

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

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6138 [题目大意] 给出一些串,询问第x个串和第y个串的公共子串, 同时要求该公共子串为某个串的前缀.求最长符合要求的答案 [题解] 我们对所有串构建AC自动机,将两个询问串之一在AC自动机上mark所有的匹配位置 另一个串在mark的地方寻找最长匹配即可 [代码] #include <cstdio> #include <algorithm> #include <cstrin

(后缀数组/Trie)HDU 6138-Fleet of the Eternal Throne

Fleet of the Eternal Throne Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 838    Accepted Submission(s): 393 Problem Description > The Eternal Fleet was built many centuries ago before the tim

MS17-010 &quot;Eternal Blue(永恒之蓝)”, 修复补丁下载汇总地址!

MS17-010  "Eternal Blue(永恒之蓝)"官方修复补丁,下载连接汇总地址 Product (Down-level) Release Date CDN Link Security Update for Windows Server 2003 for x64-based Systems (KB4012598) 5/13/2017 http://download.windowsupdate.com/d/csa/csa/secu/2017/02/windowsserver20

如何利用fleet单元文件为CoreOS集群创建高灵活性服务

提供:ZStack云计算 系列教程 本教程为CoreOS上手指南系列九篇中的第六篇. 内容简介 CoreOS能够利用一系列工具以集群化与Docker容器化方式简化服务管理工作.其中etcd负责将各独立节点联系起来并提供全局数据平台,而大部分实际服务管理任务则由fleet守护进程实现. 在上一篇教程中,我们了解了如何利用fleetctl命令操纵服务及集群成员.在今天的教程中,我们将了解如何利用单元文件定义服务. 在接下来的内容中,我们将探讨如何构建fleet单元文件,外加在生产环境下提升服务健壮性

ZOJ3741 状压DP Eternal Reality

E - Eternal Reality Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3741 Description In Academy City, most students have special abilities. Such as Railgun, Teleport, Telekinesis, AIM Stalker and

[CoreOS 转载] CoreOS实践指南(四):集群的指挥所Fleet

转载:http://www.csdn.net/article/2015-01-14/2823554/2 摘要:CoreOS是采用了高度精简的系统内核及外围定制的操作系统.ThoughtWorks的软件工程师林帆将带来“漫步云端:CoreOS实践指南”系列文章,介绍CoreOS精华和推荐的实践方法.本文为基础第四篇:集群的指挥所Fleet. 集群上的服务生命周期 刚刚的启动流程看起来很简单,不是么?在实际的使用中,如果为了省事,用Fleet启动一个服务,这样做就可以了.但这种做法其实会带来的服务管

[LeetCode] 853. Car Fleet 车队

N cars are going to the same destination along a one lane road.  The destination is target miles away. Each car i has a constant speed speed[i] (in miles per hour), and initial position position[i] miles towards the target along the road. A car can n

853.&#160;Car Fleet

https://leetcode.com/problems/car-fleet/solution/ https://leetcode.com/problems/car-fleet/discuss/139999/Easy-understanding-JAVA-TreeMap-Solution-with-explanation-and-comment N cars are going to the same destination along a one lane road.  The destin