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 exceed 106, 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

Copy
7 3
a
aa
ab
?aaab
-2
?aaab
-3
?aaab
+2
?aabbaa
output

Copy
6
4
3
6


题意:

给出n个字符串,表示n个人名,有两种操作:

?string ,统计字符串string中出现的属于城市居民的次数。

+id,把编号为id的人变为城市居民,如果已经是忽略。

-id,把编号为id的人变为不是城市居民,如果已经不是的话忽略。

现有m个操作,对于?输出结果。

思路:

我们在统计的时候其实就是沿着fail指针走,把所有的标记叠加起来,而fail指针构成了一棵fail树,所以我们在求当前节点的fail指针方向有多少个标记的时候不必一层层的fail上去了,对于每个点维护其到根的有效节点的个数即可,当更新某个点的时候,就相当于这个点的子树到根的有效节点的个数都发生了变化,将树形结构变成线性结构,在树状数组中更新即可。

 

参考代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lowbit(x) (x&-x)
#define maxn 1000010
int n,m,tot;
char s[maxn];
vector<int> vec[maxn];
int ch[maxn][],fail[maxn],val[maxn],last[maxn];
int c[maxn],in[maxn],out[maxn],tim,id[maxn],use[maxn]; inline void Modify(int x,int num)
{
if(x==) return ;
while(x<maxn)
{
c[x]+=num;
x+=lowbit(x);
}
}
inline void Add(int x,int y,int num)
{
Modify(x,num);Modify(y,-num);
}
inline int Query(int x)
{
int res=;
while(x>)
{
res+=c[x];
x-=lowbit(x);
}
return res;
} inline void Init()
{
tot=;tim=;
memset(ch[],,sizeof(ch[]));
memset(val,,sizeof(val));
memset(use,,sizeof(use));
}
inline int idx(char c){ return c-'a';}
inline void Insert(char*s,int x)
{
int u=,len=strlen(s);
for(int i=;i<len;++i)
{
int c=idx(s[i]);
if(!ch[u][c])
{
memset(ch[tot],,sizeof(ch[tot]));
val[tot]=;
ch[u][c]=tot++;
}
u=ch[u][c];
}
val[u]=x;
id[x]=u;
}
inline void GetFail()
{
queue<int> q;
fail[]=;
for(int c=;c<;++c)
{
int u=ch[][c];
if(u){ fail[u]=;q.push(u);last[u]=; }
}
//cout<<"cnt "<<cnt<<endl;
while(!q.empty())
{
int r=q.front(); q.pop();
vec[fail[r]].push_back(r);
for(int c=;c<;++c)
{
int u=ch[r][c];
if(!u){ch[r][c]=ch[fail[r]][c];continue;}
q.push(u);
int v=fail[r];
fail[u]=ch[v][c];
last[u] = val[fail[u]]?fail[u]:last[fail[u]];
}
}
}
inline void dfs(int u)
{
in[u]=++tim;
for(int i=,len=vec[u].size();i<len;++i)
dfs(vec[u][i]);
out[u]=tim;
} inline void clac(int x,int num)
{
Add(in[id[x]],out[id[x]]+,num);
} inline void work()
{
ll ans=;
int u=,len=strlen(s);
for(int i=;i<len;++i)
{
int r=idx(s[i]);
u=ch[u][r];
ans+=Query(in[u]);
}
printf("%lld\n",ans);
} int main()
{
scanf("%d%d",&m,&n);
Init();
for(int i=;i<=n;++i)
scanf("%s",s),Insert(s,i),use[i]=;
GetFail();
dfs(); for(int i=;i<=n;++i) clac(i,);
while(m--)
{
scanf("%s",s);
if(s[]=='?') work();
else
{
int x;
sscanf(s+,"%d",&x);
if(use[x]&&s[]=='-')
{
use[x] = ;
clac(x,-);
}
else if(!use[x]&&s[]=='+')
{
use[x] = ;
clac(x,);
}
}
} return ;
}
/*
7 3
a
aa
ab
?aaab
-2
?aaab
-3
?aaab
+2
?aabbaa
*/

CoderForces 163E e-Government(AC自动机+树状数组维护fail树的dfs序)的更多相关文章

  1. BZOJ_2819_Nim_树状数组维护出栈入栈序

    BZOJ_2819_Nim_树状数组维护出栈入栈序 Description 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任 ...

  2. 【树状数组套主席树】带修改区间K大数

    P2617 Dynamic Rankings 题目描述给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+ ...

  3. BZOJ 3881 [COCI2015]Divljak (Trie图+Fail树+树链的并+树状数组维护dfs序)

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

  4. POJ 3321 Apple Tree(后根遍历将树转化成序列,用树状数组维护)

    题意:一棵树,有很多分叉,每个分叉上最多有1个苹果. 给出n,接下来n-1行,每行u,v,表示分叉u,v之间有树枝相连.这里数据中u相当于树中的父节点,v相当于子节点. 给出两个操作: 1.C x  ...

  5. ACM-ICPC 2018 徐州赛区网络预赛 G. Trace【树状数组维护区间最大值】

    任意门:https://nanti.jisuanke.com/t/31459 There's a beach in the first quadrant. And from time to time, ...

  6. Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains 【树状数组维护区间最大值】

    题目传送门:http://codeforces.com/contest/799/problem/C C. Fountains time limit per test 2 seconds memory ...

  7. 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...

  8. 牛客练习赛52 B题【树状数组维护区间和{查询区间和,如果区间元素重复出现则计数一次}】补题ing

    [题目] 查询区间和,如果区间元素重复出现则计数一次. 链接:https://ac.nowcoder.com/acm/contest/1084/B [题解] 将询问按r排序,维护每个数最后出现的位置, ...

  9. HYSBZ - 3813 奇数国 欧拉函数+树状数组(线段树)

    HYSBZ - 3813奇数国 中文题,巨苟题,巨无敌苟!!首先是关于不相冲数,也就是互质数的处理,欧拉函数是可以求出互质数,但是这里的product非常大,最小都2100000,这是不可能实现的.所 ...

随机推荐

  1. vue学习笔记(五)条件渲染和列表渲染

    前言 在众多的编程语言中,我们的基础语法总是少不了一些专业语法,比如像定义变量,条件语句,for循环,数组,函数等等,vue.js这个优秀的前端框架中也有同样的语法,我们换一个名词,将条件语句改成专业 ...

  2. NW.js打包一个桌面应用

    1.安装nw(可以到官网:https://nwjs.io下载) npm install nw -g 2.创建一个最最简单的nw应用 在nwjs文件夹中 新建index.html和package.jso ...

  3. [java] 集合的架构——1张图表示

  4. 除了获取 MAC 地址还能干啥

            以前写过一篇<在Web中获取MAC地址>的文章,文章的地址是:https://www.cnblogs.com/tosser/p/9022187.html,我当时使用 OCX ...

  5. 使用 layUI做一些简单的表单验证

    使用 layUI做一些简单的表单验证 <form method="post" class="layui-form" > <input name ...

  6. 【Java】面向对象之继承

    多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可.其中如图中所示,食草动物.食肉动物.兔子.羊.狮子.豹都可以称为子类,动物类称为父 ...

  7. JS三座大山再学习(一、原型和原型链)

    原文地址 ## 前言 西瓜君之前学习了JS的基础知识与三座大山,但之后工作中没怎么用,印象不太深刻,这次打算再重学一下,打牢基础.冲鸭~~ 原型模式 JS实现继承的方式是通过原型和原型链实现的,JS中 ...

  8. 阅读《Windows 黑客编程技术详解》(甘迪文著)【正在进行】

    内容提要: 本书介绍的是黑客编程的基础技术,涉及用户层下的Windows编程和内核层下的Rootkit编程. 全书大纲: 第一篇 用户篇 平常计算机上使用的应用程序,都运行在用户层上,属于用户程序.在 ...

  9. JavaWeb01-常识

    软件系统体系结构 1        常见软件系统体系结构B/S.C/S 1.1 C/S l  C/S结构即客户端/服务器(Client/Server),例如QQ: l  需要编写服务器端程序,以及客户 ...

  10. Excel的常用函数

    1.查找重复内容=IF(COUNTIF(A:A,A2)>1,"重复","") 2.重复内容首次出现时不提示=IF(COUNTIF(A$2:A2,A2)&g ...