zoukankan      html  css  js  c++  java
  • P2444 [POI2000]病毒

    传送门

    AC自动机

    如果有一个无限长的安全串

    那么这个串在所有危险代码构成的AC自动机上一直匹配下去都不会走到结束标记

    因为如果走到结束标记说明串中有危险代码

    考虑怎样才能无限匹配

    可以发现,如果在AC自动机上从根节点出发,一直走能走出一个环的话

    那么就可以一直走这个环,从而无限匹配下去

    所以要在自动机上找环

    可以用DFS实现

    有一点要注意

    不但有结尾标记的点不能走

    如果一个点一直走 fail 能走到一个有结束标记的点

    那么这个点也不能走

    因为这串的后面一部分会包含危险代码(AC自动机的性质)

    然后就是代码了

     

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=3e4+7;
    int n;
    int c[N][2],pd[N],fail[N],cnt;
    char a[N];
    inline void ins()//插入危险代码
    {
        int u=0,l=strlen(a);
        for(int i=0;i<l;i++)
        {
            int v=a[i]-'0';
            if(!c[u][v]) c[u][v]=++cnt;
            u=c[u][v];
        }
        pd[u]=1;
    }
    queue <int> q;
    inline void pre()//预处理fail以及不能走的点
    {
        for(int i=0;i<=1;i++) if(c[0][i]) q.push(c[0][i]);
        while(!q.empty())
        {
            int u=q.front(); q.pop();
            for(int i=0;i<=1;i++)
            {
                int v=c[u][i];
                if(!v) c[u][i]=c[fail[u]][i];
                else
                {
                    fail[v]=c[fail[u]][i];
                    if(pd[fail[v]]) pd[v]=1;
                    q.push(v);
                }
            }
        }
    }
    bool vis[N],p[N];//vis表示是否走过,p表示是否在当前路径上
    inline void dfs(int x)//dfs找环
    {
        if(p[x])//如果在当前路径上,说明找到环了
        {
            cout<<"TAK";
            exit(0);
        }
        if(vis[x]||pd[x]) return;
        vis[x]=p[x]=1;
        dfs(c[x][0]); dfs(c[x][1]);
        p[x]=0;
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",a);
            ins();
        }
        pre();
        dfs(0);
        cout<<"NIE";
        return 0;
    }
  • 相关阅读:
    BugkuCtf-pwn2-exp
    Python 基础知识(一)
    C++基本语法的部分总结
    Ububtu 14.04 安装 Hadoop 2.7.3
    leetcode-Evaluate the value of an arithmetic expression in Reverse Polish Notation
    leetcode-Given a binary tree, find its minimum depth
    Java 实现 AES 加解密
    git fork代码并修改胡提交到自己的git仓库
    git使用记录_备忘
    java awt 中文乱码 显示为 方块
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9682415.html
Copyright © 2011-2022 走看看