LG2444/BZOJ2938 「POI2000」病毒 AC自动机

问题描述

LG2444

BZOJ2938


I \(\mathrm{AC}\)自动机

\(\mathrm{AC}\)自动机是一种多模式串匹配算法,本萌新今天刚学了它qwq

约定在构造\(\mathrm{AC}\)自动机的过程中,\(\mathrm{Trie}\)树上的边和由于\(\mathrm{AC}\)自动机中这一句:

else ch[x][i]=ch[fail[x]][i];

所新建的边为实边。

也就是\(x\)\(ch[x][0]\)\(ch[x][1]\)的边为实边。


II 危险!

什么样的字符串是有病毒的?包含了某个模式串的文本串。

这样的文本串一定在AC自动机上经过一个字符串的结尾节点。

我们称这样的节点是危险的。


III 解法

想象一下,假如在AC自动机上有一个环,我就可以让这个文本串一直在这个环上跑,转啊转啊转。

就像最短路有了负环一样。

所以,只要在AC自动机上,存在一个环,使得这个环上和从根到这个环的路径上,所有的点都不是危险节点,就有解,否则无解。


IV \(\mathrm{code}\)

#include<bits/stdc++.h>
using namespace std;


template <typename Tp>
void read(Tp &x){
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') {
        ch=getchar();fh=-1;
    }
    else fh=1;
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+ch-'0';
        ch=getchar();
    }
    x*=fh;
}


int n;
int ch[300000][2],tot;
bool ed[300000];
int fail[300000],root;
string s;

int chk(char s){
    return s-'0';
}

void insert(){
    int siz=s.size();int p=root;
    for(int i=0;i<siz;i++){
        int d=chk(s[i]);
        if(!ch[p][d]) ch[p][d]=++tot;
        p=ch[p][d];
    }
    ed[p]=1;
}

void pre(){
    queue<int>q;
    for(int i=0;i<2;i++){
        if(ch[root][i]) fail[ch[root][i]]=root,q.push(ch[root][i]);
    }
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=0;i<2;i++){
            if(ch[x][i]){
                fail[ch[x][i]]=ch[fail[x]][i],q.push(ch[x][i]);
                if(ed[ch[fail[x]][i]]) ed[ch[x][i]]=1; 
            }
            else ch[x][i]=ch[fail[x]][i];
        }
    }
}

bitset<300000>ins;

void dfs(int x){
    if(ins[x]){
        puts("TAK");exit(0);
    }
    ins[x]=1;
    for(int i=0;i<2;i++){
        if(!ch[x][i]||ed[ch[x][i]]) continue;
        dfs(ch[x][i]);
    }
    ins[x]=0;
}

int main(){
    read(n);
    for(register int i=1;i<=n;i++){
        cin>>s;insert();
    }
    pre();dfs(root);
    puts("NIE");
    return 0;
}
全部评论

相关推荐

最近又搬回宿舍了,在工位坐不住,写一写秋招起伏不断的心态变化,也算对自己心态的一些思考表演式学习从开始为实习准备的时候就特别焦虑,楼主一开始选择的是cpp后端,但是24届这个方向已经炸了,同时自己又因为本科非92且非科班,所以感到机会更加迷茫。在某天晚上用java写出hello&nbsp;world并失眠一整晚后选择老本行干嵌入式。理想是美好的,现实情况是每天忙但又没有实质性进展,总是在配环境,调工具,顺带还要推科研。而这时候才发现自己一直在表演式学习,徘徊在设想如何展开工作的循环里,导致没有实质性进展。现在看来当时如果把精力专注在动手写而不是两只手端着看教程,基本功或许不会那么差。实习的焦虑5月,楼主...
耶比:哲学上有一个问题,玛丽的房间:玛丽知道眼睛识别色彩的原理知道各种颜色,但是她生活在黑白的房间里,直到有一天玛丽的房门打开了她亲眼看到了颜色,才知道什么是色彩。我现在最大可能的减少对非工作事情的思考,如果有一件事困扰了我, 能解决的我就直接做(去哪里或者和谁吵架等等……),解决不了的我就不想了,每一天都是最年轻的一天,珍惜今天吧
投递比亚迪等公司10个岗位 > 秋招被确诊为…… 牛客创作赏金赛
点赞 评论 收藏
分享
喜欢吃蛋糕仰泳鲈鱼是我的神:字节可以找个hr 给你挂了,再放池子捞
点赞 评论 收藏
分享
11-09 01:22
已编辑
东南大学 Java
高级特工穿山甲:羡慕,我秋招有家企业在茶馆组织线下面试,约我过去“喝茶详谈”😢结果我去了发现原来是人家喝茶我看着
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务