E. e-Government

time limit per test:1 second
memory limit per test:256 megabytes
input:standard input
output:standard output

The best programmers of Embezzland compete to develop a part of the project called "e-Government" — the system of automated statistic collecting and press analysis.

We know that any of the k citizens can become a member of the Embezzland government. The citizens' surnames are a1, a2, ..., ak. All surnames are different. Initially all k citizens from this list are members of the government. The system should support the following options:

  • Include citizen ai to the government.
  • Exclude citizen ai from the government.
  • Given a newspaper article text, calculate how politicized it is. To do this, for every active government member the system counts the number of times his surname occurs in the text as a substring. All occurrences are taken into consideration, including the intersecting ones. The degree of politicization of a text is defined as the sum of these values for all active government members.

Implement this system.

Input

The first line contains space-separated integers n and k (1 ≤ n, k ≤ 105) — the number of queries to the system and the number of potential government members.

Next k lines contain the surnames a1, a2, ..., ak, one per line. All surnames are pairwise different.

Next n lines contain queries to the system, one per line. Each query consists of a character that determines an operation and the operation argument, written consecutively without a space.

Operation "include in the government" corresponds to the character "+", operation "exclude" corresponds to "-". An argument of those operations is an integer between 1 and k — the index of the citizen involved in the operation. Any citizen can be included and excluded from the government an arbitrary number of times in any order. Including in the government a citizen who is already there or excluding the citizen who isn't there changes nothing.

The operation "calculate politicization" corresponds to character "?". Its argument is a text.

All strings — surnames and texts — are non-empty sequences of lowercase Latin letters. The total length of all surnames doesn't exceed106, the total length of all texts doesn't exceed 106.

Output

For any "calculate politicization" operation print on a separate line the degree of the politicization of the given text. Print nothing for other operations.

Examples

input
  1. 7 3
    a
    aa
    ab
    ?aaab
    -2
    ?aaab
    -3
    ?aaab
    +2
    ?aabbaa

output

6
4
3
6

Solution

fail树的经典运用。

先建出fail树,然后用树状数组维护DFS序即可。

Code

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. #include<queue>
  7. using namespace std;
  8. #define MAXN 1000100
  9. int K,N,loc[MAXN],visit[MAXN];
  10. struct EdgeNode{int next,to;}edge[MAXN<<];
  11. int head[MAXN],cnt=;
  12. inline void AddEdge(int u,int v) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}
  13. inline void InsertEdge(int u,int v) {AddEdge(u,v); AddEdge(v,u);}
  14. char S[MAXN];
  15. namespace FailTree
  16. {
  17. int son[MAXN][],end[MAXN],sz=,fail[MAXN];
  18. #define id(str) str-'a'+1
  19. inline int Insert(int x,char str[])
  20. {
  21. int len=strlen(str+),now=;
  22. for (int i=; i<=len; i++)
  23. if (son[now][id(str[i])]) now=son[now][id(str[i])];
  24. else son[now][id(str[i])]=++sz,now=sz;
  25. end[now]=; loc[x]=now;
  26. }
  27. queue<int>q;
  28. inline void Getfail()
  29. {
  30. q.push();
  31. while (!q.empty())
  32. {
  33. int now=q.front(); q.pop();
  34. for (int i=; i<=; i++)
  35. if (son[now][i])
  36. {
  37. int fa=fail[now];
  38. while (fa && !son[fa][i]) fa=fail[fa];
  39. fail[son[now][i]]=fa? son[fa][i]:;
  40. q.push(son[now][i]);
  41. }
  42. }
  43. for (int i=; i<=sz; i++) InsertEdge(fail[i],i);
  44. }
  45. }
  46. using namespace FailTree;
  47. namespace Divide
  48. {
  49. int pl[MAXN],pr[MAXN],dfn,tree[MAXN<<];
  50. inline void DFS(int now,int last)
  51. {
  52. pl[now]=++dfn;
  53. for (int i=head[now]; i; i=edge[i].next)
  54. if (edge[i].to!=last)
  55. DFS(edge[i].to,now);
  56. pr[now]=++dfn;
  57. }
  58. inline int lowbit(int x) {return x&-x;}
  59. inline void Modify(int pos,int D) {for (int i=pos; i<=dfn; i+=lowbit(i)) tree[i]+=D;}
  60. inline int Query(int pos) {int re=; for (int i=pos; i; i-=lowbit(i)) re+=tree[i]; return re;}
  61. inline int Calc(char str[])
  62. {
  63. int len=strlen(str+),ans=,now=;
  64. for (int i=; i<=len; i++)
  65. {
  66. while (now && !son[now][id(str[i])]) now=fail[now];
  67. now=now? son[now][id(str[i])]:;
  68. ans+=Query(pl[now]);
  69. }
  70. return ans;
  71. }
  72. inline void Change(int x,int D)
  73. {
  74. if (visit[x] && D>) return;
  75. if (!visit[x] && D<) return;
  76. visit[x]^=;
  77. Modify(pl[loc[x]],D); Modify(pr[loc[x]],-D);
  78. }
  79. }
  80. using namespace Divide;
  81. int main()
  82. {
  83. scanf("%d%d",&K,&N);
  84. for (int i=; i<=N; i++) scanf("%s",S+),Insert(i,S);
  85. Getfail(); DFS(,);
  86. for (int i=; i<=N; i++) Modify(pl[loc[i]],),Modify(pr[loc[i]],-),visit[i]=;
  87. while (K--)
  88. {
  89. char opt=getchar(); int x;
  90. while (opt!='+' && opt!='-' && opt!='?') opt=getchar();
  91. switch (opt)
  92. {
  93. case '+' : scanf("%d",&x); Change(x,); break;
  94. case '-' : scanf("%d",&x); Change(x,-); break;
  95. case '?' : scanf("%s",S+); printf("%d\n",Calc(S)); break;
  96. }
  97. }
  98. return ;
  99. }

【Codeforces163E】e-Government 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. 2018.10.20 NOIP模拟 巧克力(trie树+dfs序+树状数组)

    传送门 好题啊. 考虑前面的32分,直接维护后缀trietrietrie树就行了. 如果#号不在字符串首? 只需要维护第一个#前面的字符串和最后一个#后面的字符串. 分开用两棵trie树并且维护第一棵 ...

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

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

  4. CodeForces - 1207G :Indie Album(AC自动机 fail树上DFS)

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

  5. bzoj2434 fail树 + dfs序 + 树状数组

    https://www.lydsy.com/JudgeOnline/problem.php?id=2434 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现, ...

  6. CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)

    The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...

  7. BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

    一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...

  8. 【bzoj3881】[Coci2015]Divljak AC自动机+树链的并+DFS序+树状数组

    题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

  9. 【学习笔记】ac自动机&fail树

    定义 解决文本串和多个模式串匹配的问题: 本质是由多个模式串形成的一个字典树,由tie的意义知道:trie上的每一个节点都是一个模式串的前缀: 在trie上加入fail边,一个节点fail边指向这个节 ...

随机推荐

  1. JS实现文字截取(雾)

    今天在跳板群那里看到一个神奇的样式,效果: 感觉十分神奇,因为一开始以为他是只有一个P元素包着文字然后最后一个自动截取文字,而且最后一行还可以提前截取???这怎么做到的,然后想了一下css怎么做,好像 ...

  2. iOS 3D 之 SceneKit框架Demo分析

    Scene Kit 是Apple 向 OS X 开发者们提供的 Cocoa 下的 3D 渲染框架. Scene Kit 建立在 OpenGL 的基础上,包含了如光照.模型.材质.摄像机等高级引擎特性, ...

  3. [转]ASP.NET应用程序生命周期趣谈(二)

    在上回书开始的时候我们提到博客园的IIS看了一眼我的请求后就直接交给ASP.NET去处理了,并且要求ASP.NET处理完之后返回HTML以供展示. 那么我们不仅要问: 1,    IIS肯定是没有眼睛 ...

  4. 教你怎么半天搞定Docker

    首先,不要把docker想的那么高大,它不就是先做个镜像,然后通过docker像虚拟机一样跑起来嘛...docker其实在真实业务场景中还是非常有局限性的.Dockerfile脚本也没那么好写,有些应 ...

  5. MapReduce 的架构

    主从结构 主节点,只有一个 : JobTracker   ,JobTracker 一般情况下,运行在 namenode 这台机器上. 从节点,有很多个 : TaskTrackers  ,  部署在剩下 ...

  6. [C#6] 1-using static

    0. 目录 C#6 新增特性目录 1. 老版本的代码 1 using System; 2 3 namespace csharp6 4 { 5 internal class Program 6 { 7 ...

  7. Jmeter添加硬件监控

    首先非常感谢介绍jmeter的博主,多谢您. 看了之后受益匪浅啊~~ 根据这篇博文的说法,首先进入网站 点击Jmeter-plugins.org 点击downloads 这两个都可以下载,反正都一样. ...

  8. CORS基础要点:关于dataType、contentType、withCredentials

    事实上,面试时我喜欢问跨域,因为多数开发者都知道它并且常用,而我希望能从面试者的回答中知道他在这个问题的深入程度,进一步看看面试者研究问题的思维方式及钻研精神,然而确实难到了很多人,当然这也不是面试通 ...

  9. 快速排序算法 quick sort的理解

    最近做了一下算法的一些练习,感觉基础薄弱了,只是用一些已经有的东西来完成练习如quickSort(c++使用的时候是sort(起始位置,终止位置,比较函数),这个需要加头文件),但是不知道怎么推出来, ...

  10. fixed数据类型

    在处理图形运算,特别是3D图形生成运算时,往往要定义一个Fixed数据类型,我称它为定点数,定点数其时就是一个整形数据类型,他的作用就是把所有数 进行转换,从而得到相应类型的整型表达,然后使用定点数进 ...