1. 程式人生 > >【題解】P2444 病毒

【題解】P2444 病毒

show uil href pac 給定 就是 dfs using cpp

【題解】[P2444 POI2000]病毒

一道\(ac\)自動機好題...

考慮危險的字符串是什麽意思,就是在這個文本串中有模式串的匹配,這樣的匹配可以通過\(ac\)自動機完成。
那麽給定一個字符串如何判斷是否有病毒,直接就是看ac自動機是否匹配成功。

考慮“無限長的安全字符串”代表什麽意思,就是在\(ac\)自動機找到一個環。可以用閹割版的\(tarjin\)

#include<bits/stdc++.h>

using namespace std;
#define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)
#define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
#define ERP(t,a) for(register int t=head[a];t;t=e[t].nx)
#define Max(a,b) ((a)<(b)?(b):(a))
#define Min(a,b) ((a)<(b)?(a):(b))
#define midd register int mid=(l+r)>>1
#define TMP template < class ccf >

TMP inline ccf qr(ccf b){
    char c=getchar();
    int q=1;
    ccf x=0;
    while(c<48||c>57)
    q=c==45?-1:q,c=getchar();
    while(c>=48&&c<=57)
    x=x*10+c-48,c=getchar();
    return q==-1?-x:x;
}

const int maxac=30005;
int n;
string x;
struct AC{
    int son[2];
    int fail;int cnt;
    inline int& operator [](int o){
    return son[o&1];
    }
    inline int& operator [](char o){
    return son[(o-‘0‘)&1];
    }
}ac[maxac];
int act;

inline void build(int lit){
    int now=0;
    RP(t,0,lit-1){
    if(!ac[now][x[t]])
        ac[now][x[t]]=++act;
    now=ac[now][x[t]];
    }
    ac[now].cnt++;
    //cout<<"build="<<now<<endl;
}

queue< int > q;
inline void gen(){
    RP(t,0,1)
    if(ac[0][t])
        q.push(ac[0][t]);
    while(!q.empty()){
    int now=q.front();
    q.pop();
    RP(t,0,1){
        if(ac[now][t]){
        ac[ac[now][t]].fail=ac[ac[now].fail][t];
        ac[ac[now][t]].cnt|=ac[ac[ac[now].fail][t]].cnt;
        q.push(ac[now][t]);
        }
        else
        ac[now][t]=ac[ac[now].fail][t];
    }
    }
}

bool in[maxac];
bool usd[maxac];
void dfs(int now){
    usd[now]=in[now]=1;
    RP(t,0,1){
    if(in[ac[now][t]])
        puts("TAK"),exit(0);
    if(!ac[ac[now][t]].cnt)
        dfs(ac[now][t]);
    }
    in[now]=0;
}


int main(){
#ifndef ONLINE_JUDGE
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
#endif
    n=qr(1);
    RP(t,1,n){
    cin>>x;
    build(x.length());
    }
    gen();
    if(!ac[0].cnt)
    dfs(0);
    puts("NIE");
    return 0;
}

【題解】P2444 病毒