题目链接
思路
建好AC自动机,用DFS判环。
代码
#include <cstdio>
#include <cstring>
const int maxn=30000;
struct ac_automaton
{
int son[maxn+10][2],cnt,fail[maxn+10],danger[maxn+10],q[maxn+10],head,tail,vis[maxn+10],fuck[maxn+10];
inline int clear()
{
memset(son,0,sizeof son);
memset(fail,0,sizeof fail);
memset(danger,0,sizeof danger);
cnt=0;
return 0;
}
inline int ins(char* s)
{
int now=0,ls=strlen(s);
for(register int i=0; i<ls; ++i)
{
if(!son[now][s[i]-'0'])
{
son[now][s[i]-'0']=++cnt;
}
now=son[now][s[i]-'0'];
}
danger[now]=1;
return 0;
}
inline int build()
{
head=tail=0;
for(register int i=0; i<=1; ++i)
{
if(son[0][i])
{
q[++tail]=son[0][i];
fail[son[0][i]]=0;
}
}
while(head!=tail)
{
int u=q[++head];
for(register int i=0; i<=1; ++i)
{
if(son[u][i])
{
int now=fail[u];
while(now&&(!son[now][i]))
{
now=fail[now];
}
fail[son[u][i]]=son[now][i];
if(danger[fail[son[u][i]]])
{
danger[son[u][i]]=1;
}
q[++tail]=son[u][i];
}
else
{
son[u][i]=son[fail[u]][i];
}
}
}
return 0;
}
int dfs(int now)
{
vis[now]=1;
for(register int i=0; i<=1; ++i)
{
if(vis[son[now][i]])
{
return 1;
}
if(danger[son[now][i]]||fuck[son[now][i]])
{
continue;
}
fuck[son[now][i]]=1;
if(dfs(son[now][i]))
{
return 1;
}
}
vis[now]=0;
return 0;
}
};
char s[maxn+10];
int n;
ac_automaton ac;
int main()
{
scanf("%d",&n);
ac.clear();
for(register int i=1; i<=n; ++i)
{
scanf("%s",s);
ac.ins(s);
}
ac.build();
puts(ac.dfs(0)?"TAK":"NIE");
return 0;
}