Prelude

传送到Codeforces:(/ω\)……… (/ω•\)


Solution

很水的一道题。

对查询的串建出来AC自动机,然后树上随便跑跑就行了。

为什么要写这篇题解呢?

我第一眼看到这个题:“哈哈,有根树上的路径信息查询,点分治就好了,被我秒啦!”

“这个题好像是某Qualification Round的题啊。。。怎么Qual就出点分治啊,真毒瘤。”

然后码码码。。。

“怎么TLE了,卡卡常。”

卡常ing。。。

“怎么又WA了,难道卡哈希?毒瘤毒瘤。”

debugging。。。

“算了调不出来了拿tourist的代码拍一下吧。”

“这场比赛怎么AK了三百个人啊?这题怎么代码这么短啊?”

“。。。似乎KMP然后dfs一下就没了。。。我简直药丸。。。”

然后事实证明KMP的复杂度是错的,很容易就卡掉了,卡的方法也很简单,大家自己想想吧。。。

如果用KMP的话是TLE on test 30,如果是比赛就直接FST了。。。

所以用AC自动机就没问题了喵~


Code

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue> using namespace std;
const int MAXN = 400010;
int _w; int n, ch[MAXN], m;
char str[MAXN]; namespace G {
int head[MAXN], nxt[MAXN], to[MAXN], eid;
void init() {
eid = 0;
memset(head, -1, sizeof head);
}
void adde( int u, int v ) {
to[eid] = v, nxt[eid] = head[u], head[u] = eid++;
}
} void add_edge( int u, int v, char *str ) {
for( char *p = str; *p; ++p ) {
ch[++m] = *p - 'a';
if( p == str ) G::adde(u, m);
else G::adde(m-1, m);
}
G::adde(m, v);
} namespace AC {
int ch[MAXN][26], nid;
bool word[MAXN];
queue<int> q;
int f[MAXN]; void insert( char *s ) {
int u = 0;
for( ; *s; ++s ) {
int c = *s - 'a';
if( !ch[u][c] )
ch[u][c] = ++nid;
u = ch[u][c];
}
word[u] = 1;
}
void build() {
for( int i = 0; i < 26; ++i )
if( ch[0][i] )
q.push( ch[0][i] );
while( !q.empty() ) {
int u = q.front(); q.pop();
for( int i = 0; i < 26; ++i ) {
int v = ch[u][i];
if( !v ) {
ch[u][i] = ch[f[u]][i];
continue;
}
int w = f[u];
while( w && !ch[w][i] ) w = f[w];
f[v] = ch[w][i];
q.push(v);
}
}
}
} int ans;
void solve( int u, int o ) {
using namespace G;
if( ch[u] != -1 ) {
o = AC::ch[o][ch[u]];
if( AC::word[o] ) ++ans;
}
for( int i = head[u]; ~i; i = nxt[i] )
solve( to[i], o );
} int main() {
_w = scanf( "%d", &n );
m = n;
G::init();
for( int i = 2; i <= n; ++i ) {
int pa;
_w = scanf( "%d%s", &pa, str );
add_edge(pa, i, str);
}
for( int i = 1; i <= n; ++i )
ch[i] = -1;
_w = scanf( "%s", str );
AC::insert(str);
AC::build();
solve(1, 0);
printf( "%d\n", ans );
return 0;
}

【题解】Tree-String Problem Codeforces 291E AC自动机的更多相关文章

  1. 【题解】P3796【模板】AC自动机(加强版)

    [题解]P3796 [模板]AC自动机(加强版) 记录当前\(cnt\)是第几个"星".记录第几个串是对应着第几个星. 这里补充一点对于\(AC\)自动机的理解.可能一直有个问题我 ...

  2. Codeforces 710F - String Set Queries(AC 自动机)

    题面传送门 题意:强制在线的 AC 自动机. \(n,\sum|s|\leq 3\times 10^5\) 如果不是强制在线那此题就是道 sb 题,加了强制在线就不那么 sb 了. 这里介绍两种做法: ...

  3. Searching the String - ZOJ 3228(ac自动机)

    题目大意:首先给你一下母串,长度不超过10^5,然后有 N(10^5) 次查询,每次查询有两种命令,0或者1,然后加一个子串,询问母串里面有多少个子串,0表示可以重复,1表示不可以重复.   分析:发 ...

  4. AC 自动机学习笔记

    虽然 NOIp 原地爆炸了,目前进入 AFO 状态,但感觉省选还是要冲一把,所以现在又来开始颓字符串辣 首先先复习一个很早很早就学过但忘记的算法--自动 AC AC自动机. AC 自动机能够在 \(\ ...

  5. AC自动机模板2(【CJOJ1435】)

    题面 Description 对,这就是裸的AC自动机. 要求:在规定时间内统计出模版字符串在文本中出现的次数. Input 第一行:模版字符串的个数N. 第2->N+1行:N个字符串.(每个模 ...

  6. 洛谷P2444 病毒【AC自动机】

    题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段,试问,是否 ...

  7. BZOJ1195 [HNOI2006]最短母串 AC自动机 bfs

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 传送门 - BZOJ1195 题意概括 给出一堆串,然后求一个包含这些串的所有串的最短的中的字典序最小的. 题解 先造一个AC ...

  8. 【poj2778-DNA Sequence】AC自动机+矩阵乘法

    题意: (只含AGCT)给定m个病毒串,让你构造一个长度为n的字符串(也只含有AGCT),问有多少种方案.n很大:1<=n<=2000000000 题解: 用病毒串建立AC自动机(num个 ...

  9. Trie树&kmp&AC自动机&后缀数组&Manacher

    Trie 计数+Trie,读清题意很重要 https://vjudge.net/problem/UVALive-5913 kmp AC自动机 模板:https://vjudge.net/problem ...

随机推荐

  1. find 删除文件

    find 目录 -type f -name '*' -print0 | xargs -0 rm

  2. Linux 学习记录 20170218

    一.Linux 硬件查看命令     ----/proc 文件系统是一种内核和内核模块用来向进程(process) 发送信息的机制.我们可以从这个文件里获取到系统的相关信息. 1.显卡信息dmesg ...

  3. 20162325 金立清 S2 W3 C13

    20162325 2017-2018-2 <程序设计与数据结构>第3周学习总结 教材学习内容概要 查找是在一组项内找到指定目标或是确定目标不存在的过程 高效的查找使得比较的次数最少 Com ...

  4. POJ 1239 Increasing Sequences 动态规划

    题目链接: http://poj.org/problem?id=1239 Increasing Sequences Time Limit: 1000MSMemory Limit: 10000K 问题描 ...

  5. DocX插件

    DocX是一个用C#编写的.NET库,它允许开发人员以简单直观的方式操作Word文件.

  6. Week 2

    第1章:概论1.原文“这些软件企业的商业模式有些事合情合理也合法:有些看似合情合理,但不怎么合法:有些做法不合 理,但是还没有出台相关的法律.在相关法律完善之前,软件行业还有一个行规,即应该有职业道德 ...

  7. ADO.NET使用using关闭数据库连接

    using (SqlConnection conn = new SqlConnection(source)) { // open the connoction conn.Open(); // Do s ...

  8. 旧文备份:CANopen协议中SDO服务

    SDO是服务数据对象接口(Service Data Obiect)的缩写,顾名思义提供服务数据的访问接口,服务数据就是一些实时性要求不高的数据,一般是指节点配置参数,因此,SDO一般用来配置和获得节点 ...

  9. grunt入门讲解3:实例讲解使用 Gruntfile 配置任务

    这个Gruntfile 实例使用到了5个 Grunt 插件: grunt-contrib-uglify      grunt-contrib-qunitgrunt-contrib-concatgrun ...

  10. 使用docker inspect获取数据卷信息时返回地址为空

    使用 docker inspect 命令查看容器挂载的volume的目录 $ sudo docker inspect --format "{{.Volumes}}" redis-m ...