题意:有N个串,给出的形式是拼接给出,对于第i行:  (1,c)表示字符串i是单个字母c; (2,p,c)表示字符串i=在字符串p后面接上一个字母c。

然后给出M个提问,形式是(i,string)。问string在字符串i中出现了多少次。

思路:这类题显然是在AC自动机上乱搞。  对于询问的串建立AC自动机,BFS建立fail树;那么一个询问其实就是第i个串的位置到根的这些节点,有多少个在string节点的子树里。      即给一条链染色,然后询问一个点是子树里多少点被染色了。 为了不重不漏,  我们用回溯就可以处理了。 然后用树状数组维护DFS序下的前缀和。

具体的,对于N个串在AC自动机上跑,每跑一步对应N个字符串之一。 每跑到一个节点,就加加。 跑完子树后就减减,保证了加的部分是一条链。

  1. #include<bits/stdc++.h>
  2. #define pii pair<int,int>
  3. #define pb push_back
  4. #define rep(i,a,b) for(int i=a;i<=b;i++)
  5. using namespace std;
  6. const int maxn=;
  7. vector<pii>G[maxn],Q[maxn];
  8. vector<int>F[maxn];
  9. int ch[maxn][],fail[maxn],ans[maxn],tot;
  10. int in[maxn],out[maxn],times; //dfn
  11. char s[maxn]; int sum[maxn];
  12. void add(int x,int val){ while(x<=times) sum[x]+=val,x+=(-x)&x;}
  13. int query(int x){ int res=; while(x){ res+=sum[x]; x-=(-x)&x; } return res;}
  14. int add()
  15. {
  16. int now=,L=strlen(s);
  17. rep(i,,L-) {
  18. if(!ch[now][s[i]-'a']) ch[now][s[i]-'a']=++tot;
  19. now=ch[now][s[i]-'a'];
  20. } return now;
  21. }
  22. void build()
  23. {
  24. queue<int>q;
  25. rep(i,,) if(ch[][i]) q.push(ch[][i]);
  26. while(!q.empty()){
  27. int u=q.front(); q.pop();
  28. rep(i,,) {
  29. if(ch[u][i]){
  30. fail[ch[u][i]]=ch[fail[u]][i];
  31. q.push(ch[u][i]);
  32. }
  33. else ch[u][i]=ch[fail[u]][i];
  34. }
  35. }
  36. rep(i,,tot) F[fail[i]].push_back(i);
  37. }
  38. void dfs(int u)
  39. {
  40. in[u]=++times;
  41. for(int i=;i<F[u].size();i++) dfs(F[u][i]);
  42. out[u]=times;
  43. }
  44. void dfs(int u,int now) //u是位置,now是id
  45. {
  46. add(in[u],);
  47. for(int i=;i<Q[now].size();i++){
  48. pii t=Q[now][i];
  49. ans[t.second]=query(out[t.first])-query(in[t.first]-);
  50. }
  51. for(int i=;i<G[now].size();i++){
  52. pii t=G[now][i];
  53. dfs(ch[u][t.first],t.second);
  54. }
  55. add(in[u],-);
  56. }
  57. int main()
  58. {
  59. int N,M,opt,p;
  60. scanf("%d",&N);
  61. rep(i,,N) {
  62. scanf("%d",&opt);
  63. if(opt==) p=;
  64. else scanf("%d",&p);
  65. scanf("%s",s);
  66. G[p].pb(pii(s[]-'a',i));
  67. }
  68. scanf("%d",&M);
  69. rep(i,,M) {
  70. scanf("%d%s",&p,s);
  71. Q[p].pb(pii(add(),i));
  72. }
  73. build();
  74. dfs();
  75. dfs(,);
  76. rep(i,,M) printf("%d\n",ans[i]);
  77. return ;
  78. }

CodeForces - 1207G :Indie Album(AC自动机 fail树上DFS)的更多相关文章

  1. AC自动机fail树上dfs序建线段树+动态memset清空

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=4117 思路:https://blog.csdn.net/u013306830/article/detail ...

  2. CF G. Indie Album AC自动机+fail树+线段树

    这个套路挺有意思的. 把 $trie$ 和 $fail$ 树都建出来,然后一起跑一跑就好了~ #include <queue> #include <cstdio> #inclu ...

  3. ac自动机fail树上按询问建立上跳指针——cf963D

    解法看着吓人,其实就是为了优化ac自动机上暴力跳fail指针.. 另外这题对于复杂度的分析很有学习价值 /* 给定一个母串s,再给定n个询问(k,m) 对于每个询问,求出长度最小的t,使t是s的子串, ...

  4. 洛谷2414(构建ac自动机fail树dfs序后遍历Trie树维护bit及询问答案)

    要点 这是一道蔡队题,看我标题行事 任意询问y串上有多少个x串,暴力找每个节点是不是结尾肯定是炸的,考虑本质:如果某节点是x的结尾,根据ac自动机的性质,x一定是此(子)串后缀.又有每个Trie节点的 ...

  5. BZOJ 2905: 背单词 AC自动机+fail树+dfs序+线段树

    Description 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使得其中的每个单词是后一个单词的子串,最大化子序列中W的和. Input 第一行一个整数TEST,表示数据组 ...

  6. BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)

    题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...

  7. 【BZOJ-2434】阿狸的打字机 AC自动机 + Fail树 + DFS序 + 树状数组

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2022  Solved: 1158[Submit][Sta ...

  8. 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组

    E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...

  9. 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序

    3881: [Coci2015]Divljak Time Limit: 20 Sec  Memory Limit: 768 MBSubmit: 508  Solved: 158[Submit][Sta ...

随机推荐

  1. 【07月01日】A股滚动市净率PB历史新低排名

    2010年01月01日 到 2019年07月01日 之间,滚动市净率历史新低排名. 上市三年以上的公司,2019年07月01日市净率在30以下的公司. 来源:A股滚动市净率(PB)历史新低排名. 1 ...

  2. 用Python 绘制分布(折线)图

    用Python 绘制分布(折线)图,使用的是 plot()函数. 一个简单的例子: # encoding=utf-8 import matplotlib.pyplot as plt from pyla ...

  3. Docker安装mysql、nginx、redis、tomcat

    拉取mysql 5.7官方镜像 docker pull mysql:5.7 启动容器 docker run --name mysql5.7 -p 3306:3306 -e MYSQL_ROOT_PAS ...

  4. [转帖]JVM性能调优详解

    JVM性能调优详解 https://www.cnblogs.com/secbro/p/11833651.html 应该是 jdk8 以前的方法 貌似permsize 已经放弃这一块了. 前面我们学习了 ...

  5. 关于AQS的一点总结

    关于AQS的一点总结 2017年03月13日 09:48:13 那只是一股逆流 阅读数:772    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/ ...

  6. Java学习:数据结构简介

    数据结构 数据结构: 数据结构_栈:先进后出 入口和出口在同一侧 数据结构_队列:先进先出 入口和出口在集合的两侧 数据结构_数组: 查询快:数组的地址是连续的,我们通过数组的首地址可以找到数组,通过 ...

  7. Linux(二)各种实用命令

    继续Linux命令学习,没有什么捷径,每个命令都去敲几遍就熟悉了,第二篇学习的是一些比较实用类的命令,主要是从开发的角度进行学习,并不深入,话不多说,开始! 一.系统管理类 1.1 stat --st ...

  8. php 安装imap报错“configure: error: utf8_mime2text() has new signature”解决

    环境:php官方docker镜像 php:7.2-apache 安装IMAP扩展模块执行命令:docker-php-ext-install imap 报错信息:configure: error: ut ...

  9. Python pip安装第三方库的国内镜像

    Windows系统下,一般情况下使用pip在DOS界面安装python第三方库时,经常会遇到超时的问题,导致第三方库无法顺利安装,此时就需要国内镜像源的帮助了. 使用方法如下: 例如:pip inst ...

  10. 前端1-----CSS层叠样式表了解,css的引入方式,三大选择器(标签,类,id),高级选择器

    前端1-----CSS层叠样式表了解,css的引入方式,三大选择器(标签,类,id),高级选择器 一丶CSS简介    叠样式表(英文全称:Cascading Style Sheets)是一种用来表现 ...