zoukankan      html  css  js  c++  java
  • 【POI2000】病毒

    Description

    给定若干模式串,求是否存在一个无限长的文本串使得所有模式串均不能在此文本串中匹配。

    Solution

    这是一道AC自动机的变式,我们首先将这些模式串在Trie树上存储,以便AC自动机的操作。

    我们这样思考:在我们存储Trie时,我们将每一个串的末尾标记一下,表示这是一个模式串的结尾,那么如果存在题目描述的文本串,那么意味着这个文本串在AC自动机上不会转移到任何一个标记节点,只会在一个环上不断转移,那么我们只需要找到这个环是否存在即可,很显然,找环可以从0节点dfs一遍。注意如果一个节点的fail节点如果是标记节点,那么它自身也是标记节点,因为该节点的fail节点到根节点的串是该节点到根节点的串的后缀。

    所以我们只需要构造AC自动机,然后进行dfs即可。

    Code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 int n;
     5 char c[30010];
     6 int tot, ch[300100][2], f[300010], vis[300010], pd[300010], val[300010];
     7 void insert(char *a) {
     8     int now = 0;
     9     int l = strlen(a);
    10     for (register int i = 0; i < l; ++i) {
    11         if (!ch[now][a[i] - '0']) ch[now][a[i] - '0'] = ++tot;
    12         now = ch[now][a[i] - '0'];
    13     }
    14     val[now] = 1;
    15 }
    16 queue <int> q;
    17 void bfs() {
    18     for (register int i = 0 ; i < 2; ++i)
    19         if (ch[0][i]) {
    20             f[ch[0][i]] = 0;
    21             q.push(ch[0][i]);
    22         }
    23     while (!q.empty()) {
    24         int now = q.front();
    25         q.pop();
    26         for (register int i = 0; i < 2; ++i) {
    27             if (ch[now][i]) {
    28                 f[ch[now][i]] = ch[f[now]][i];
    29                 val[ch[now][i]] |= val[f[ch[now][i]]];
    30                 q.push(ch[now][i]);
    31             }
    32             else ch[now][i] = ch[f[now]][i];
    33         }
    34     }
    35 }
    36 void dfs(int now) {
    37     if (pd[now]) {
    38         puts("TAK");
    39         exit(0);
    40     }
    41     if (vis[now] || val[now]) return ;
    42     vis[now] = pd[now] = 1;
    43     dfs(ch[now][0]);
    44     dfs(ch[now][1]);
    45     pd[now] = 0;
    46 }
    47 int main() {
    48     scanf("%d", &n);
    49     for (register int i = 1; i <= n; ++i) {
    50         scanf("%s", c);
    51         insert(c);
    52     }    
    53     bfs();
    54     dfs(0);
    55     puts("NIE");
    56     return 0;
    57 }
    AC Code
  • 相关阅读:
    【转】linux清屏的几种方法
    【转】Ubuntu 64位系统安装交叉编译环境一直提醒 没有那个文件或目录
    【转】无法获得锁 /var/lib/dpkg/lock
    层级原理图设计方法
    【转】gcc 编译使用动态链接库和静态链接库
    【转】设置 vim 显示行号永久有效
    【转】VMware 全屏显示
    emwin之自绘制 BUTTON 图形的一些问题
    使用 sizeof 获取字符串数组的大小
    emwin之2D图形流位图显示的方法
  • 原文地址:https://www.cnblogs.com/shl-blog/p/11261961.html
Copyright © 2011-2022 走看看