[POI 2000] 病毒

Posted evenbao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POI 2000] 病毒相关的知识,希望对你有一定的参考价值。

[题目链接]

         https://www.lydsy.com/JudgeOnline/problem.php?id=2938

[算法]

        首先建出给定字符串集的AC自动机

        存在无限长的代码当且仅当 : AC自动机上存在一个环且环上没有危险节点

        时间复杂度 : O(N)

[代码]

       

#include<bits/stdc++.h>
using namespace std;
#define MAXP 300010
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

int n;
char s[MAXP];

struct AC_Automation
{
    int sz , rt , timer;
    int fail[MAXP];
    bool danger[MAXP] , vis[MAXP] , ins[MAXP];
    int child[MAXP][2];
    inline void init()
    {
        timer = 0;
        sz = 0;
        rt = newnode();
    }
    inline void chkmin(int &x , int y)
    {
        x = min(x , y);
    }
    inline int newnode()
    {
        ++sz;
        child[sz][0] = child[sz][1] = -1;
        fail[sz] = danger[sz] = 0;
        return sz;
    }
    inline void insert(char *s)
    {
        int now = rt;
        for (int i = 1; i <= strlen(s + 1); i++)
        {
            int nxt = s[i] - 0;
            if (child[now][nxt] == -1) child[now][nxt] = newnode();
            now = child[now][nxt];
        }
        danger[now] = 1;
    }
    inline void rebuild()
    {
        queue< int > q;
        fail[rt] = rt;
        for (int i = 0; i < 2; i++)
        {
            if (child[rt][i] == -1)
                child[rt][i] = rt;
            else
            {
                fail[child[rt][i]] = rt;
                q.push(child[rt][i]);
            }
        }
        while (!q.empty())
        {
            int cur = q.front();
            q.pop();
            for (int i = 0; i < 2; i++)
            {
                if (child[cur][i] == -1)
                    child[cur][i] = child[fail[cur]][i];
                else
                {
                    fail[child[cur][i]] = child[fail[cur]][i];
                    danger[child[cur][i]] |= danger[fail[child[cur][i]]];
                    q.push(child[cur][i]);
                }
            }
        }
    }
    inline void solve(int now)
    {
        if (ins[now])
        {
            printf("TAK
");
            exit(0);
        }
        if (vis[now] || danger[now]) return;
        vis[now] = ins[now] = 1;
        if (child[now][0] != -1) solve(child[now][0]);
        if (child[now][1] != -1) solve(child[now][1]);
        ins[now] = 0;
    } 
} ACAM;

template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void read(T &x)
{
   T f = 1; x = 0;
   char c = getchar();
   for (; !isdigit(c); c = getchar()) if (c == -) f = -f;
   for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - 0;
   x *= f;
}

int main()
{
    
    scanf("%d" , &n);
    ACAM.init();
    for (int i = 1; i <= n; i++)
    {
        scanf("%s" , s + 1);
        ACAM.insert(s); 
    }
    ACAM.rebuild();
    ACAM.solve(1);
    printf("NIE
");
    
    return 0;
}

 

以上是关于[POI 2000] 病毒的主要内容,如果未能解决你的问题,请参考以下文章

Poi2000病毒

[Poi2000]病毒

P2444 [POI2000]病毒

bzoj 2938: [Poi2000]病毒

2938. [POI2000]病毒AC自动机

BZOJ2938 [Poi2000]病毒 AC自动机