【BZOJ】2938: [Poi2000]病毒

题意

\(n\)个01病毒串,总长不超过\(30000\)。问是否存在无限长的不包含病毒串的01串。

分析

考虑ac自动机,如果不包含病毒串而且无限长也就是说存在一个环(转移和fail树),使得环上不含病毒串。

题解

所以我们标记一下病毒串后dfs找环即可。

#include <bits/stdc++.h>
using namespace std;
const int N=30005;
int ch[N][2], tot, go[N], vis[N], ins[N], q[N], f[N];
bool dfs(int x) {
    ins[x]=1;
    vis[x]=1;
    for(int i=0; i<2; ++i) {
        int y=ch[x][i];
        if(ins[y]) {
            return 1;
        }
        if(go[y] || vis[y]) {
            continue;
        }
        if(dfs(y)) {
            return 1;
        }
    }
    ins[x]=0;
    return 0;
}
int main() {
    int n;
    scanf("%d", &n);
    for(int i=0; i<n; ++i) {
        int c=getchar(), now=0;
        for(; c!=48 && c!=49; c=getchar());
        for(; c==48 || c==49; c=getchar()) {
            c-=48;
            now=ch[now][c]?ch[now][c]:(ch[now][c]=++tot);
        }
        go[now]=1;
    }
    int *fr=q, *ta=q;
    *ta++=0;
    for(; fr!=ta; ) {
        int x=*fr++;
        for(int i=0; i<2; ++i) {
            int &y=ch[x][i], z=ch[f[x]][i];
            if(y) {
                *ta++=y;
                if(x) {
                    f[y]=z;
                    go[y]|=go[z];
                }
            }
            else {
                y=z;
            }
        }
    }
    puts(dfs(0)?"TAK":"NIE");
    return 0;
}

转载于:https://www.cnblogs.com/iwtwiioi/p/4985804.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值