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