Mike and Friends(CodeForces - 547E,AC自动机fail树dfs序上建可持久化线段树)

【CodeForces - 163E】:e-Government【AC自动机fail树上dfs序+树状数组】 题目: CodeForces - 163E:e-Government 题意: 给出 K个模式串,N 次操作:(1)删除一个模式串(2)添加一个模式串(K个中的某一个)(3)给出一个主串,问模式串在主串中总共出现了多少次 笔记: fail树: AC自动机上每一个节点都有唯一的fail指针,那么将fail指针逆转后,所有的 fail指针和节点将形成一颗有根树 根据 fail指针的定义... 阅读详情

一、题目链接

Mike and Friends

二、题目大意

有 n n n 个字符串 s 1 , s 2 , ⋯   , s n s_1,s_2,\cdots,s_n s1​,s2​,⋯,sn​ 和 q q q 次询问.

定义函数 f ( S , T ) f(S,T) f(S,T) 为字符串 S S S 在字符串 T T T 中的出现次数.

每次询问给出三个整数 l , r , k l,r,k l,r,k 表示询问 ∑ i = l r f ( s i , s k ) \sum_{i=l}^{r}{f(s_i,s_k)} ∑i=lr​f(si​,sk​).

1 ≤ n ≤ 2 × 1 0 5 , 1 ≤ q ≤ 5 × 1 0 5 , 1 ≤ ∑ ∣ s i ∣ ≤ 2 × 1 0 5 , 1 ≤ l ≤ r ≤ n , 1 ≤ k ≤ n 1 \leq n \leq 2 \times 10^5, 1 \leq q \leq 5 \times 10^5, 1 \leq \sum{|s_i|} \leq 2 \times 10^5, 1 \leq l \leq r \leq n, 1 \leq k \leq n 1≤n≤2×105,1≤q≤5×105,1≤∑∣si​∣≤2×105,1≤l≤r≤n,1≤k≤n.

三、分析

首先考虑一个弱化问题,假设每次询问 l = 1 , r = n l=1,r=n l=1,r=n,即只有 k k k 在变化. 显然,我们可以进行如下预处理:对 n n n 个字符串建立 AC 自动机,在每个字符串的每个前缀对应的字典树节点上 + 1 +1 +1. 查询的答案即为 s k . e n d ( ) s_k.end() sk​.end() 对应字典树节点的fail子树和. 如上问题可使用AC自动机fail树dfs序上建线段树解决.

对于原问题,与弱化问题相比 l , r l,r l,r 都在变化,只需要将线段树升级成可持久化线段树即可.

四、代码实现

#include <bits/stdc++.h>
using namespace std;

const int M = (int)2e5;
const int N = (int)17;

string s[M + 5];

struct Trie {
	int tot;
	int fail[M + 5], q[M + 5], pos[M + 5];
	int nx[M + 5][26], go[M + 5][26];

	void clear() {
		tot = 0;
		memset(nx[tot], 0, sizeof nx[tot]);
	}

	int newnode() {
		++tot;
		memset(nx[tot], 0, sizeof nx[tot]);
		return tot;
	}

	void insert(int id) {
		int u = 0;
		for(int i = 0, v; i < (int)s[id].size(); ++i) {
			v = s[id][i] - 'a';
			if(nx[u][v] == 0) nx[u][v] = newnode();
			u = nx[u][v];
		}
		pos[id] = u;
	}

	void build() {
		int l = 1, r = 0;
		fail[0] = 0;
		for(int i = 0; i < 26; ++i) if(nx[0][i]) {
			go[0][i] = nx[0][i];
			fail[nx[0][i]] = 0;
			q[++r] = nx[0][i];
		} else go[0][i] = 0;
		while(l <= r) {
			int u = q[l++];
			for(int i = 0; i < 26; ++i) if(nx[u][i]) {
				go[u][i] = nx[u][i];
				fail[nx[u][i]] = go[fail[u]][i];
				q[++r] = nx[u][i];
			} else go[u][i] = go[fail[u]][i];
		}
	}

	vector<int> g[M + 5];
	int st[M + 5], en[M + 5], dfn;
	struct segTree {
		int tot;
		int rt[M + 5];
		int lc[2 * M * (N + 1) + M + 5], rc[2 * M * (N + 1) + M + 5];
		int sum[2 * M * (N + 1) + M + 5];

		void clear() {
			tot = 0;
			lc[tot] = 0, rc[tot] = 0;
		}

		void update(int x, int y, int l, int r, int a, int b) {
			if(l == r) return;
			int mid = (l + r) >> 1;
			if(a <= mid) {
				int lcx = lc[x];
				sum[++tot] = sum[lc[x]] + b;
				lc[y] = tot, rc[y] = rc[x];
				update(lcx, lc[y], l, mid, a, b);
			} else {
				int rcx = rc[x];
				sum[++tot] = sum[rc[x]] + b;
				lc[y] = lc[x], rc[y] = tot;
				update(rcx, rc[y], mid + 1, r, a, b);
			}
		}

		int query(int x, int y, int l, int r, int a, int b) {
			if(a <= l && r <= b) return sum[y] - sum[x];
			int mid = (l + r) >> 1, s = 0;
			if(a <= mid) s += query(lc[x], lc[y], l, mid, a, b);
			if(mid < b)  s += query(rc[x], rc[y], mid + 1, r, a, b);
			return s;
		}
	} tr;

	void dfs(int u) {
		st[u] = ++dfn;
		for(const int &v: g[u]) dfs(v);
		en[u] = dfn;
	}

	void gao(int n) {
		for(int i = 0; i <= tot; ++i) g[i].clear();
		for(int i = 1; i <= tot; ++i) g[fail[i]].push_back(i);
		dfn = 0; dfs(0);
		for(int i = 0; i < n; ++i) {
			tr.rt[i + 1] = ++tr.tot;
			for(int j = 0, u = 0; j < (int)s[i].size(); ++j) {
				u = go[u][s[i][j] - 'a'];
				if(j == 0) tr.update(tr.rt[i], tr.rt[i + 1], 1, tot + 1, st[u], 1);
				else tr.update(tr.rt[i + 1], tr.rt[i + 1], 1, tot + 1, st[u], 1);
			}
		}
	}

	int query(int l, int r, int k) {
		return tr.query(tr.rt[l - 1], tr.rt[r], 1, tot + 1, st[pos[k - 1]], en[pos[k - 1]]);
	}
} trie;

void work() {
	int n, q; cin >> n >> q;
	trie.clear();
	for(int i = 0; i < n; ++i) {
		cin >> s[i];
		trie.insert(i);
	}
	trie.build();
	trie.gao(n);
	for(int i = 0, l, r, k; i < q; ++i) {
		cin >> l >> r >> k;
		cout << trie.query(l, r, k) << "\n";
	}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	work();
	return 0;
}

模板 - AC自动机 AC自动机模板 阅读详情

相关推荐

别只盯着Spectre!Cadence Virtuoso里APS和Spectre X该怎么选?一份给模拟IC新手的指南

本文深入解析Cadence Virtuoso中的三大仿真引擎Spectre、APS和Spectre X,帮助模拟IC新手根据电路规模、精度需求和计算资源做出智能选择。通过对比技术指标和应用场景,提供射频电路、混合信号系统和电源管理IC的优化仿真策略,显著提升设计效率。

weixin_26841743的博客 707

ac自动机fail树上dfs序建可持久化线段树

#include <cstring> #include <cstdio> #define max(a,b) a>b?a:b const int mn=300005; struct Trie{ int father,fail,next[26]; void init(){ father=fail=0; memset(next,0,sizeof next);...

冷月寒笙的博客 1824

WRF后处理总结:wrf-python与NCL在WRF后处理中的基本应用——变量提取、计算与可视化

判断需要提取的变量与诊断量确定后,使用getvar函数进行提取。可使用ncdump-h命令查看wrfout中的变量,wrf中的诊断量分类也可从官方文档处查阅。判断绘图类型所需的可视化绘图类型,决定了你在WRF后处理中的计算步骤。1D点线图:ll_to_xy interpline2D填色图:interplevel3D剖面图:vinterp vertcross绘图、美化色标、XY轴、标签的设置等等。

weixin_43750300的博客 1万+

AC自动机算法模板

PS:还不是很会,上午刚学,把仅学的一点先记录下来,肯定有错,学会了再来纠正(逃。 测试题目:http://acm.hdu.edu.cn/showproblem.php?pid=2222 想学自动AC机,忽然发现当初最开始学习时听到的一句话如今真的学到这里了:AC自动机fail树上dfs序建可持久化线段树。嘤 AC自动机 = KMP + Trie时间复杂度O((n+m)*L) 具体思想,...

nEo.大魔王 1035

保姆级教程:用Docker Compose在Linux上一键部署Milvus 2.5.8(附配置文件详解)

本文提供了一份详细的Milvus 2.5.8安装指南,通过Docker Compose在Linux系统上一键部署这款高性能向量数据库。教程涵盖环境准备、配置文件解析、服务启动验证及常见问题解决,帮助开发者快速搭建AI应用所需的基础设施。

weixin_28829629的博客 269

Windows 必看!OpenClaw 一键安装教程|告别报错,一次成功不踩坑

OpenClaw 完整安装与配置的全流程教程

m0_70389289的博客 1085

CF 163E //AC自动机fail树上建线段树 || 建树状数组+差分

题目 题意 n(1e6)n(1e6)n(1e6)个询问,kkk个模式串(总长度(1e6)(1e6)(1e6))。 询问: 1:给定串sss求,sss串里模式串出现几次。 2:将第iii个串删除(若已经删除无视此操作。 2:将第iii个串恢复(若已经存在无视此操作。 思路 建立AC自动机,在fail树上,用当前结点去更新后代。 可以在fail树上先序dfs序dfs序dfs序上维护线段树(区间更新,单...

Rshs 1338

什么是信噪比?信噪比越大好还是越小好?

在进行声音增强的时候,往往需要考虑声音信号和噪声的信噪比,那么信噪比是什么呢?越大越好还是越小越好,此处引入百度百科的解读: 信噪比,英文名称叫做SNR或S/N(SIGNAL-NOISE RATIO),又称为讯噪比。是指一个电子设备或者电子系统中信号与噪声的比例。这里面的信号指的是来自设备外部需要通过这台设备进行处理的电子信号,噪声是指经过该设备后产生的原信号中并不存在的无规则的额外信号(或信息),并且该种信号并不随原信号的变化而变化。 同样是“原信号不存在”还有一种东西叫“失真”,失真和噪声实际上有一

码匀的博客 7万+

uva11481

此题纠结了我一段时间了。今天在acseed的提示下我ac了。。 首先题目很容易就可以想到首先算出前面C(m,k)种方案。那么就要考虑其他的n-k个位置都要不在其位置上。 那么我首先想到了错排。但是不知道为什么如果这么算的话是错误的。以5,3,2为例,答案是12,但是用错排算却是6错的。我就不知道为什么了。 求大神指教我上面的想法为什么错了啊。 然后被提醒说是容斥原理,首先第一步还是C(m,

lyc 933

【OpenClaw企业级智能体实战】第32篇:政企版OpenClaw安全落地指南——奇安信55页报告深度拆解与实战

2026年Q2,OpenClaw(俗称“龙虾”)安全风险集中爆发,公安部、工信部等监管机构密集发声,23万公网暴露实例、155个高危漏洞让企业“养虾”安全压力骤增。奇安信发布的55页《政企版龙虾安全使用指南》,以“看得清、管得住、用得好”为核心,构建了“端-网-云”三层防护体系。本文深度拆解这份报告的九大安全面与三大趋势,全景扫描奇安信、腾讯、360等头部厂商安全方案,提炼企业最低安全基线与实操配置,通过金融机构虚拟案例演示落地全流程,提供从资产摸底、规范制定到工具部署的完整解决方案。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 573

开发simulink 以及stm32半物理仿真碰到的问题,以及处理方法,Error:External Mode Open Protocol Connect command failed(实测有用)

串口实现的,但是在测试的时候发现,这个串口可以正常发送和接收数据,但是一旦把这个串口只让其进行版物理仿真就报错。直接刷写程序是可以的,最后查到问题了。我要实现半物理仿真,就是通过matlab实现可以直接控制stm32板子,实际上是通过xcp on。然后点击simulink上的观测按钮就可以直接和stm32平台进行通讯了。3,还是使用串口3,但是重新需要设置一下com口,因为重新插拔了一下,按照这个设置方法就可以。2,重新加载ioc文件。

pvmsmfchcs的博客 1500

【模板】AC自动机

ACM模板 目录插入以及构建AC自动机【模板】AC自动机(二次加强版)ac自动机fail树上dfs序建可持久化线段树 插入以及构建AC自动机 #include<queue> #include<string> const int N=200010; struct node { int chd[26],fail,cnt; }tree[N]; void insert(string s) { int p=0; for(int i=0;i<s.size();i+

Fighting_Peter的博客 399

YOLOv5源码逐行超详细注释与解读(5)——配置文件yolov5s.yaml

全网最详细的YOLOv5源码解读之配置文件yaml。逐行注释,逐句讲解,一文带你了解yaml。小白必看!

路人贾的博客 1万+

Codeforces Round #305 (Div. 1)E. Mike and Friends(AC自动机+fail树dfs序+主席树)

传送门 题意:给定n个字符串,q次询问,每次给出正整数L,R,X,要求输出第x个字符串在第l个字符串到第r个字符串的总匹配次数。 (字符串长度之和不大于2e5) 分析: 首先我们考虑对于一个字符串集合,我们如何求出其中某个字符串在集合中的匹配次数?比如给定集合cacaa,baabaa,aa。求出aa在集合中的总匹配次数。(易知答案是4) 。 我们可以把所有的串插入AC自动机,再用aa去trie树上匹配,随后统计fail树上每个子树的点权和。 aa的尾节点的匹配次数就是答案了。 为什么呢?因为在fail树

矮纸斜行闲作草 277

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

CodeForces 547E Mike and Friends AC自动机 主席树

题意: 给出\(n\)个字符串\(s_i\)和\(q\)个询问: \(l,r,k\):\(\sum\limits_{i=l}^{r}count(i, k)\),其中\(count(i,j)\)表示\(s_j\)作为子串在\(s_i\)中出现的次数 分析: 先不考虑查询中\(l,r\)的限制,考虑该字符串\(s_k\)在一个字符串集合中出现的次数。 先将这个字符串集合插入到一棵Trie数中,并且...

weixin_30379911的博客 93

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

codeforces #305 E Mike and friends

原问题可以转化为:给定第k个字符串,求它在L-R的字符串里作为子串出现了多少次 定义子串为字符串的某个前缀的某个后缀(废话) 等价于我们把一个字符串插入到trie里,其过程中每个经过的节点和其向上的fail链上的点都是该字符串的子串 又因为对于一条fail链,u向上能访问到v当前仅当u在v的子树内 那么原问题又变成了: 将L-R个字符串按照上述方法插入到trie中并将经过的节点...

weixin_30549657的博客 88

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

bzoj3881 [Coci2015]Divljak(AC自动机+fail树+dfs序+树状数组+树链剖分)

bzoj3881 [Coci2015]Divljak 原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3881 题意: Alice有n个字符串S1,S2...Sn" role="presentation" style="position: relative;">S1,S2...SnS1,S2...SnS_1,S_2...S_n,Bob

Bfk的博客 1145

C - Permutation Counting UVALive - 5092 dp

题目链接 题意: 给出n和m,我们有一个由1~n组成的n个数字的数列a[],如果a[i]>i,我们就把ans++,我们要求出ans==m的数列有多少个。 思路: 直接按照dp的思想,我们考虑每增加一个数那么它只会是E-VAL的值要么不变 要么增加1 那么dp[i][j]就表示第i个数j E-val 的数列个数,可得出此动态转移方程 dp[i][j]=(dp[i][j]+(j+1)*

Marcus-Bao的个人主页 521

[COCI2015]Divljak

题目大意 有 nnn 个字符串 S1,S2,⋯ ,SnS_1, S_2, \cdots, S_nS1​,S2​,⋯,Sn​ 和一个字符串集合 TTT,一开始 TTT 为空。 然后有两个操作: 1 P 往 TTT 里加一个字符串 PPP。 2 x 询问集合 TTT 中有多少个字符串包含串 SxS_xSx​ (我们称串 AAA 包含串 BBB,当且仅当 BBB 是 AAA 的子串)。 对于 100%100\%100% 的数据,1≤n,q≤1051 \leq n,q \leq 10^51≤n,q≤105,字符

orz 232

CodeForces - 547E Mike and Friends

题意: 给定 nnn 个由小写字母组成的字符串,qqq 次询问,每次询问 l,r,kl, r, kl,r,k,表示求 sks_ksk​ 在 sl,sl+1,⋯ ,srs_l, s_{l+1}, \cdots, s_rsl​,sl+1​,⋯,sr​ 中出现的次数。(n,q≤2×105)(n, q \leq 2×10^5)(n,q≤2×105) 链接: https://vjudge.net/probl...

weixin_44059127的博客 285

机器学习模型的本质:数据驱动的条件反射协议

机器学习模型并非具备认知能力的智能体,而是一种基于统计相关性的输入-输出映射机制。其核心原理是通过海量数据拟合特征与目标间的数学关系,形成稳定但脆弱的‘条件反射协议’。这种协议高度依赖数据分布一致性,一旦遭遇概念漂移、分布偏移或特征泄露,性能便急剧衰减。技术价值在于将业务规则转化为可计算、可监控、可迭代的工程化组件;典型应用场景覆盖智能风控、工业质检、推荐系统与医疗辅助决策等关键领域。本文深入剖析模型的四层架构、生命周期管理及真实落地中的隐性陷阱,直击‘能跑通却不敢上线’的核心痛点。

weixin_30596343的博客 232

Codeforces 547E

不明白这个题为啥会是div1E。。。 套路的,给所有串建个AC自动机,插入的时候给路径打标记,这样统计一个串在[l,r][l,r][l,r]中出现了多少次就等价于统计在这个点fail树的子树中有多少个[l,r][l,r][l,r]间的标记,直接将询问离线后扫描线,对dfs序用树状数组维护即可。 时间复杂度O((∑i=1n∣si∣+q)log⁡n)\mathcal O((\sum_{i=1}^{n}...

mayaohua 308

【题解】Codeforces 963D. Frequency of String AC自动机

给定字符串S(1e5)S(1e5)S(1e5),有q(1e5)q(1e5)q(1e5)个询问,每次给定一个整数kik_iki​和字符串mim_imi​。 让你从SSS中选择一个子串TTT,且mim_imi​在TTT中出现了至少kik_iki​次。 保证mim_imi​的长度之和不超过1e51e51e5,保证所有的mim_imi​不相同。 这道题的关键在最后的两个保证上。 使用AC自动机可以求得所......

秋叶红于二月花 682

Codeforces 163E (AC自动机&fail树+dfs序+树状数组)

http://codeforces.com/contest/163/problem/E 实在不好意思,自己画的时候确实有点粗心,感谢大家的提醒。。这次图应该画对了。。 题意:给你几个串,然后后面有些操作,分别是给你一个文本串问哪些模式串在文本串出现了多少次,剩下两个分别就是删除一些字符串,和恢复一些字符串。 做法:AC自动机,(据说还有后缀数组。。不会),如果做过阿狸的打字机这道题应该知道怎...

KXL5180的博客 519

Codeforces AC自动机 题目汇总

86C codeforces 149E. Martian Strings 163E 291E

qq_39898877的博客 700

HDU - 4117 GRE Words (AC自动机+Fail树+线段树+DFS序+DP)

GRE Words Problem Description Recently George is preparing for the Graduate Record Examinations (GRE for short). Obviously the most important thing is reciting the words. Now George is workin

LP_Cong 3604
上一篇: SDNU_LqbTraining_2022_1【解题报告】
下一篇: CTF之MISC常用工具
The___Flash
博客等级 码龄8年 79粉丝 223原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值