LG2444 / BZOJ2938 "POI2000" virus

Problem Description

LG2444

BZOJ2938


The I \ (\ mathrm the AC} {\) automaton

\ (\ mathrm {AC} \ ) automatic machine is a multi-string matching algorithm, this adorable new today just learned it qwq

In the configuration convention \ (\ mathrm {AC} \ ) during automatic machine, \ (\ mathrm Trie} {\) side of the tree and because \ (\ mathrm {AC} \ ) automaton that a:

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

The new real side edge.

I.e. \ (X \) to \ (ch [x] [0 ] \) and \ (ch [x] [1 ] \) of the real side edge.


II hazard!

What kind of strings is a virus? It contains a text string pattern string.

Such a text string after the end of a certain node of a string on the AC automaton.

We call such a node is dangerous.


Solution III

Imagine, if there is a ring on the AC automatic machine, I can make the text string has been run in this ring, turn ah ah turn.

Like most short-circuit ring has the same negative.

Therefore, as long as the AC automaton, the presence of a ring, the ring so that the upper and the path from the root to the ring, all the node points is not dangerous, there are solutions, or no solution.


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;
}

Guess you like

Origin www.cnblogs.com/liubainian/p/11478856.html