• BZOJ2938: [Poi2000]病毒(AC自动机)


    Orz wlp 5min讲完后缀数组

    题意

    给出$n$个0, 1串

    问是否可以构造出一个无限长的字符串使其不包含任意串

    Sol

    刚开始我试图假装自己不知道这是个AC自动机的题然后来做。发现根本不可能qwq。

    如果知道这题可以用AC自动机的话就好做很多了吧。

    考虑我们构造的串中哪些子串不能出现。

    1、给出的这$n$个串显然不能出现—>本身

    2、包含这个$n$个串的串显然不能出现—> fail树

    因此我们在每个串结束的地方打上标记,同时如果一个串的fail树上任意节点被打过标记,那么这个节点一定是不能访问的。

    那最后怎么统计答案呢?

    考虑无限长的串一定可以被表示成某个串repeat~repeat~repeat~

    所以我们从根节点开始,判断是否能形成环就行了。

    10min写完没调1Ahhh

    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    const int MAXN = 1e6 + 10, B = 2;
    int N;
    int ch[MAXN][2], fa[MAXN], fail[MAXN], flag[MAXN], tot = 0, root = 0;
    char s[MAXN];
    void insert(char *s) {
        int N = strlen(s + 1), now = root;
        for(int i = 1; i <= N; i++) {
            int nxt = s[i] - '0';
            if(!ch[now][nxt]) ch[now][nxt] = ++tot;
            now = ch[now][nxt];
        }
        flag[now] = 1;
    }
    void GetFail() {
        queue<int> q;
        for(int i = 0; i < B ;i++) 
            if(ch[root][i])
                fail[ch[root][i]] = root, q.push(ch[root][i]);
        while(!q.empty()) {
            int p = q.front(); q.pop();
            for(int i = 0; i < B; i++) {
                if(ch[p][i]) fail[ch[p][i]] = ch[fail[p]][i], flag[ch[p][i]] |= flag[fail[ch[p][i]]], q.push(ch[p][i]);
                else ch[p][i] = ch[fail[p]][i];
            }
        }
    }
    int f[MAXN], vis[MAXN];
    void dfs(int x) {
        f[x] = 1;
        for(int i = 0; i < B; i++) {
            if(f[ch[x][i]] == 1) {puts("TAK"); exit(0);}
            else if(!flag[ch[x][i]] && f[ch[x][i]] != 2) dfs(ch[x][i]);
        }
        f[x] = 2;
    }
    int main() {
        scanf("%d", &N);
        for(int i = 1; i <= N; i++) {
            scanf("%s", s + 1);
            insert(s);
        }
        GetFail();
        dfs(root);
        puts("NIE");
        return 0;
    } 
    /*
    3
    011
    11 
    00000
    
    */
  • 相关阅读:
    Linux中权限管理之文件特殊权限
    Linux中权限管理之ACL权限
    Linux用户管理命令
    【并发编程】实现多线程的几种方式
    “数据中台”的再思考
    软件工程六大设计原则总结,案例演示
    你必须要知道的移动端开发知识
    【搞定面试官】你还在用Executors来创建线程池?会有什么问题呢?
    EasyCode实现数据库到Swagger全自动化
    【Java实例】使用Thumbnailator生成缩略图(缩放、旋转、裁剪、水印)
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9395013.html
Copyright © 2020-2023  润新知