链接
https://loj.ac/p/10062
题意
判断是否存在一个无限长的 $01$ 串不存在任何一个给出的 $01$ 串。
思路
建立 AC 自动机。
要有无限长的 01 串,我们需要在 Trie 图上找到一个环,且不能经过任意一个给出的串。
我们给每个串的结束的位置打上标记,通过 fail 指针传递标记,然后在 Trie 图 上 DFS 即可。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
   | #include <bits/stdc++.h> #define SZ(x) (int)(x).size() #define ALL(x) (x).begin(),(x).end() #define PB push_back #define EB emplace_back #define MP make_pair #define FI first #define SE second using namespace std; typedef double DB; typedef long double LD; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; typedef vector<int> VI; typedef vector<PII> VPII;
  const int N=3e4+5; int tr[N][2],fail[N],sz; bool f[N],st[N],ins[N]; void insert(const string &s) {     int u=0;     for(auto c:s) {         int v=c-'0';         if(!tr[u][v]) tr[u][v]=++sz;         u=tr[u][v];     }     f[u]=true; } void build() {     queue<int> q;     for(int v=0;v<2;v++) if(tr[0][v]) q.push(tr[0][v]);     while(SZ(q)) {         int u=q.front();         q.pop();         for(int v=0;v<2;v++) {             if(tr[u][v]) {                 fail[tr[u][v]]=tr[fail[u]][v];                 f[tr[u][v]]|=f[fail[tr[u][v]]];                 q.push(tr[u][v]);             }             else tr[u][v]=tr[fail[u]][v];         }     } } bool dfs(int u) {     if(ins[u]) return true;     if(st[u]||f[u]) return false;     ins[u]=st[u]=true;     if(dfs(tr[u][0])) return true;     if(dfs(tr[u][1])) return true;     ins[u]=false;     return false; } int main() {     ios::sync_with_stdio(false);     cin.tie(nullptr);     int n;cin>>n;     for(int i=1;i<=n;i++) {         string s;cin>>s;         insert(s);     }     build();     cout<<(dfs(0)?"TAK":"NIE")<<'\n';     return 0; }
   |