题目
做法
我们要找出无限安全字符串,则是这段字符串没有任意一点作为危险字符串的末点
我们对所有危险的字符串建AC自动机,然后跑一遍(trie)图,然后暴力判断是否有环,有环则说明存在无限安全字符串
My complete code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef int LL;
const LL maxn=40000;
LL tree[maxn][2],nod=1,flag[maxn],fail[maxn];
inline void Insert(char *s){
LL Len(strlen(s+1)),now(0);
for(LL i=1;i<=Len;++i){
LL c=s[i]-'0';
if(tree[now][c]==0)
tree[now][c]=++nod;
now=tree[now][c];
}flag[now]=true;
}
char s[maxn];
inline void F_fail(){
queue<LL>que;
for(LL i=0;i<2;++i)
if(tree[0][i])
que.push(tree[0][i]);
while(que.size()){
LL u=que.front(); que.pop();
flag[u]|=flag[fail[u]];
for(LL i=0;i<2;++i){
LL v(tree[u][i]);
if(v){
fail[v]=tree[fail[u]][i];
que.push(v);
}else
tree[u][i]=tree[fail[u]][i];
}
}
}
LL visit[maxn],forever[maxn];
void Dfs(LL u){
if(flag[u]) return;
if(visit[u]){
printf("TAK");
exit(0);
}
if(forever[u]) return;
visit[u]=true,forever[u]=true;
for(LL i=0;i<2;++i){
LL v(tree[u][i]);
if(v) Dfs(v);
}
visit[u]=false;
}
LL n;
int main(){
scanf("%d",&n);
for(LL i=1;i<=n;++i){
scanf(" %s",s+1);
Insert(s);
}
F_fail();
Dfs(0);
printf("NIE");
return 0;
}