病毒
题目
解析
首先要明白:若存在合法解,则一定有无限循环
于是考虑构造AC自动机,发现一个点的危险标记可以转移到一个
n
x
t
nxt
nxt为它的点,于是BFS时处理即可,然后DFS找环,找到就TAK,找不到就NIE
当然了,要对每个节点只进行一次访问,不然ybtoj会T掉两个点(洛谷脚造的数据,这都不卡)
code:
#include<queue>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define rr register int
using namespace std;
struct AC_easy
{
int tot=1,ch[30010][2],nxt[30010],k;
bool bo[30010],to[30010],vis[30010];
queue <int> b;
inline void insert(char *s)
{
int len=strlen(s),now=1;
for(rr i=0;i<len;++i)
{
if(!ch[now][s[i]-'0'])ch[now][s[i]-'0']=++tot;
now=ch[now][s[i]-'0'];
}
bo[now]=1;
}
inline void bfs()
{
for(rr i=0;i<=1;++i)ch[0][i]=1;
b.push(1);
while(b.size())
{
k=b.front(),b.pop();
for(rr i=0;i<=1;++i)
{
if(!ch[k][i])ch[k][i]=ch[nxt[k]][i];
else bo[k]|=bo[nxt[k]],nxt[ch[k][i]]=ch[nxt[k]][i],b.push(ch[k][i]);
}
}
}
inline void dfs(int now)
{
if(to[now]){printf("TAK"),exit(0);}
if(vis[now])return;
to[now]=vis[now]=1;
if(!bo[ch[now][0]])dfs(ch[now][0]);
if(!bo[ch[now][1]])dfs(ch[now][1]);
to[now]=0;
return;
}
}AC;
char s[30010];
int n,t;
int main()
{
scanf("%d",&n);
for(rr i=1;i<=n;++i)scanf("%s",&s),AC.insert(s);
AC.bfs(),AC.dfs(1);
printf("NIE");
return 0;
}