zoukankan      html  css  js  c++  java
  • 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
    ",ac.check(x,y));
            }
        }
        return 0;
    }
  • 相关阅读:
    Android ActionBar应用实战,高仿微信主界面的设计
    Android ActionBar完全解析,使用官方推荐的最佳导航栏(下) .
    Android ActionBar完全解析,使用官方推荐的最佳导航栏(上)
    actionBar兼容2.1及以上版本的做法 .
    Android UI开发详解之ActionBar .
    Android ActionBar详解(三):ActionBar实现切换Tabs标签
    Android ActionBar详解(二):ActionBar实现Tabs标签以及下拉导航 .
    完毕port(CompletionPort)具体解释
    Java的递归算法
    shell语法简单介绍
  • 原文地址:https://www.cnblogs.com/MeowMeowMeow/p/7393541.html
Copyright © 2011-2022 走看看