[POI 2000] 病毒
Posted evenbao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[POI 2000] 病毒相关的知识,希望对你有一定的参考价值。
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=2938
[算法]
首先建出给定字符串集的AC自动机
存在无限长的代码当且仅当 : AC自动机上存在一个环且环上没有危险节点
时间复杂度 : O(N)
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXP 300010 typedef long long ll; typedef long double ld; typedef unsigned long long ull; int n; char s[MAXP]; struct AC_Automation { int sz , rt , timer; int fail[MAXP]; bool danger[MAXP] , vis[MAXP] , ins[MAXP]; int child[MAXP][2]; inline void init() { timer = 0; sz = 0; rt = newnode(); } inline void chkmin(int &x , int y) { x = min(x , y); } inline int newnode() { ++sz; child[sz][0] = child[sz][1] = -1; fail[sz] = danger[sz] = 0; return sz; } inline void insert(char *s) { int now = rt; for (int i = 1; i <= strlen(s + 1); i++) { int nxt = s[i] - ‘0‘; if (child[now][nxt] == -1) child[now][nxt] = newnode(); now = child[now][nxt]; } danger[now] = 1; } inline void rebuild() { queue< int > q; fail[rt] = rt; for (int i = 0; i < 2; i++) { if (child[rt][i] == -1) child[rt][i] = rt; else { fail[child[rt][i]] = rt; q.push(child[rt][i]); } } while (!q.empty()) { int cur = q.front(); q.pop(); for (int i = 0; i < 2; i++) { if (child[cur][i] == -1) child[cur][i] = child[fail[cur]][i]; else { fail[child[cur][i]] = child[fail[cur]][i]; danger[child[cur][i]] |= danger[fail[child[cur][i]]]; q.push(child[cur][i]); } } } } inline void solve(int now) { if (ins[now]) { printf("TAK "); exit(0); } if (vis[now] || danger[now]) return; vis[now] = ins[now] = 1; if (child[now][0] != -1) solve(child[now][0]); if (child[now][1] != -1) solve(child[now][1]); ins[now] = 0; } } ACAM; template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); } template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘; x *= f; } int main() { scanf("%d" , &n); ACAM.init(); for (int i = 1; i <= n; i++) { scanf("%s" , s + 1); ACAM.insert(s); } ACAM.rebuild(); ACAM.solve(1); printf("NIE "); return 0; }
以上是关于[POI 2000] 病毒的主要内容,如果未能解决你的问题,请参考以下文章