[bzoj2938]病毒
建AC自动机后dfs看是否有环
注意建AC自动机的时候要更新val
- 代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e6+5;
struct trie{
int ch[2],fail;
int ifend;
}t[N];
int root=0,cnt;
inline void ins(char ch[]){
int len=strlen(ch+1);
int cur=root;
for(int i=1;i<=len;i++){
int c=ch[i]-'0';
if(t[cur].ch[c])cur=t[cur].ch[c];
else cur=t[cur].ch[c]=++cnt;
}
t[cur].ifend=true;
}
queue<int>q;
inline void ACautomaton_build(){
for(int i=0;i<=1;i++){
if(t[root].ch[i]){
t[t[root].ch[i]].fail=root;
q.push(t[root].ch[i]);
}
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<=1;i++){
if(t[u].ch[i]){
t[t[u].ch[i]].fail=t[t[u].fail].ch[i];
q.push(t[u].ch[i]);
t[t[u].ch[i]].ifend|=t[t[t[u].ch[i]].fail].ifend;
}
else t[u].ch[i]=t[t[u].fail].ch[i];
}
}
}
bool inst[N];
char s[N];
bool vis[N];
bool ans=false;
inline void dfs(int u){
if(ans)return;
vis[u]=true;
inst[u]=true;
for(int i=0;i<=1;i++)if(!t[t[u].ch[i]].ifend){
if(vis[t[u].ch[i]]){ans=true;return;}
if(!inst[t[u].ch[i]])dfs(t[u].ch[i]);
}
vis[u]=false;
}
int n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%s",s+1);
ins(s);
}
ACautomaton_build();
dfs(root);
if(ans)printf("TAK\n");
else printf("NIE\n");
}