AC自动机+DFS

#include <cstdio>
#include <queue>
#include <cstring>
using namespace std; #define D(x) const int MAX_LEN = * (1e4) + ;
const int MAX_NODE_NUM = MAX_LEN;
const int MAX_CHILD_NUM = ; struct Trie
{
int next[MAX_NODE_NUM][MAX_CHILD_NUM];
int fail[MAX_NODE_NUM];
int node_cnt;
bool vis[MAX_NODE_NUM]; //set it to false
bool virus[MAX_NODE_NUM];
int root; void init()
{
node_cnt = ;
root = newnode();
memset(vis, , sizeof(vis));
memset(virus, , sizeof(virus));
} int newnode()
{
for (int i = ; i < MAX_CHILD_NUM; i++)
next[node_cnt][i] = -;
virus[node_cnt++] = false;
return node_cnt - ;
} int get_id(char a)
{
return a - '';
} void insert(char buf[])
{
int now = root;
for (int i = ; buf[i]; i++)
{
int id = get_id(buf[i]);
if (next[now][id] == -)
next[now][id] = newnode();
now = next[now][id];
}
virus[now] = true;
D(printf("virus[%d] = %d\n", now, virus[now]));
} void build()
{
queue<int>Q;
fail[root] = root;
for (int i = ; i < MAX_CHILD_NUM; i++)
if (next[root][i] == -)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while (!Q.empty())
{
int now = Q.front();
Q.pop();
for (int i = ; i < MAX_CHILD_NUM; i++)
if (next[now][i] == -)
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]]=next[fail[now]][i];
if (virus[fail[next[now][i]]])
virus[next[now][i]] = true;
Q.push(next[now][i]);
}
}
} bool dfs(int u)
{
D(printf("%d\n", u));
vis[u] = true;
for (int i = ; i < MAX_CHILD_NUM; i++)
{
int v = next[u][i];
D(printf(" %d\n", v));
if (virus[v])
continue;
if (vis[v])
return true;
if (dfs(v))
return true;
}
vis[u] = false;
return false;
} void debug()
{
for(int i = ;i < node_cnt;i++)
{
printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],virus[i]);
for(int j = ;j < MAX_CHILD_NUM;j++)
printf("%2d",next[i][j]);
printf("]\n");
}
}
}ac; char st[MAX_LEN];
int n; int main()
{
scanf("%d", &n);
ac.init();
for (int i = ; i < n; i++)
{
scanf("%s", st);
ac.insert(st);
}
ac.build();
memset(ac.vis, , sizeof(ac.vis));
if (ac.dfs(ac.root))
puts("TAK");
else
puts("NIE");
return ;
}

hnu10104的更多相关文章

随机推荐

  1. Mastering Web Application Development with AngularJS 读书笔记(三)

    第一章笔记 (三) 一.Factories factory 方法是创建对象的另一种方式,与service相比更灵活,因为可以注册可任何任意对象创造功能.例如: myMod.factory('notif ...

  2. 密码学初级教程(一)基本概念及DES加密算法

    密码技术在网络通信中广泛使用,本节是初步接触密码学技术的笔记. 第1章 加密-解密 破译 明文-密文 密钥 密码算法 对称密码-公钥密码(非对称密码) 单向散列函数-散列值 消息认证码 数字签名 伪随 ...

  3. JavaScript中 window.parent 、window.top、window.self代表的含义

    在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中套了好几层frameset或者iframe),self是当前窗口, opener是用open方法 ...

  4. ELK常见错误分析(转)

    ELK 常见错误处理   ELK 这里就不介绍了,如何安装请参考博客之前的文章.在这里感谢ttlsa团队,同时,我很荣幸能加入到ttlsa团队中,分享点滴,凉白开说发文章有红包,期待这篇群主能给多少红 ...

  5. 清北暑假模拟day1 生活

    /* 数字三角形,要求第K大的值,可以推知,如果得知k的范围,那么一定是在上一行可转移状态的对应范围内(反证法可以证明),这个在背包九讲里也有提及 */ #include<cstdio> ...

  6. iSCSI配置流程

    Windows群集两个节点:分别在SQL01和SQL02设置连接共享磁盘: 此前已经在存储服务器通过StarWind创建了三个虚拟磁盘:Quemon+data+backup:starwind安装请参考 ...

  7. WCF基础知识

    根据微软官方的解释,WCF(之前的版本名为“Indigo”)是使用托管代码建立和运行面向服务(Service Oriented)应用程序的统一框架.它使得开发者能够建立一个跨平台的安全.可信赖.事务性 ...

  8. SpringMVC的Controller方法的参数不能直接绑定List、Set、Map

    List需要绑定在对象上,而不能直接写在Controller方法的参数中. http://www.iteye.com/topic/973918

  9. PHP拦截器之__set()与__get()的理解与使用

    “一般来说,总是把类的属性定义为private,这更符合现实的逻辑.但是,对属性的读取和赋值操作是非常频繁的,因此在PHP5中,预定义了两个函数“__get()”和“__set()”来获取和赋值其属性 ...

  10. 《深入浅出WPF》笔记四

    1.WPF资源分布:数据库.资源文件.WPF对象资源.变量2.每个WPF的界面都具有一个名为Resources的属性,其类型为ResourceDictionary,以键值对的形式存储资源.3.检索资源 ...