改了一下午 对着题解对拍 发现tot少了200多 并且GetFail函数里面有一个2744节点反复进入队列 不知道为什么
//思路:
//假设现在有一个无限长的不包含题目要求的代码段的字符串
//那么把它放到AC自动机上面 就会发生如下的现象
//他会在AC自动机上绕圈 不会触发警报
//所以我们在AC自动机上找环就行了
#include<bits/stdc++.h>
using namespace std;
#define int short
const int N = 2e3+5;
const int M= 3e4+5;
string t[N];
int n,tot,tree[M][2],check[N],vis[N],res[N],fail[N];
void insert(string s,int id){
int u = 0;
for(int i = 0; i<s.size(); i++){
int v = s[i]-'0';
if(!tree[u][v]) tree[u][v]=++tot;
u = tree[u][v];
}
check[u]=1;
}
void GetFail(){
queue<int>q;
for(int i = 0; i<2; i++){
if(tree[0][i]){
q.push(tree[0][i]);
}
}
while(!q.empty()){
int tmp = q.front();
q.pop();
for(int i = 0; i<2; i++){
if(tree[tmp][i]){
q.push(tree[tmp][i]);
fail[tree[tmp][i]] = tree[fail[tmp]][i];
}
else{
tree[tmp][i]=tree[fail[tmp]][i];
}
}
check[tmp]|=check[fail[tmp]];
}
}
bool dfs(int x){
vis[x]=1;
for(int i = 0; i<2; i++){
int v = tree[x][i];
if(vis[v]) return 1;
if(check[v] || res[v]) continue;
res[v]=1;
if(dfs(v)) return 1;
}
vis[x]=0;
return 0;
}
signed main(){
cin>>n;
for(int i = 1; i<=n; i++){
cin>>t[i];
insert(t[i],i);
}
GetFail();
int tmp = dfs(0);
if(tmp) cout<<"TAK";
else cout<<"NIE";
return 0;
}