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. Magicodes.Pay,打造开箱即用的统一支付库,已提供ABP模块封装

    Magicodes.Pay,打造开箱即用的统一支付库,已提供ABP模块封装 简介 Magicodes.Pay,是心莱科技团队提供的统一支付库,相关库均使用.NET标准库编写,支持.NET Framew ...

  2. getClass()和instanceof以及类的equals方法

    在比较两个类时,常见有两种做法,一种是x.getClass() == y; 一种是x instanceof y,下面我们来比较这两种做法的区别. getClass()返回一个对象所属的类 public ...

  3. 使用Rider中搭建specflow+xunit+selenium对web页面进行自动化功能测试环境

    运行rider,创建测试解决方案,选择xunit,点击create创建 ​   导入包,由于本人使用chrome浏览器(需先下载好对应的浏览器驱动),所以导入了selenium.webdriver.c ...

  4. 必知必会的JavaJDK工具

    JDK中有很多用于监控诊断的系统工具,对于Java程序员来说,无疑是用来了解自己程序运行时性能好坏的强大工具. 在JDK的bin目录下就可以找到这些工具. JPS 在Linux有一个命令叫做ps,可以 ...

  5. .NET单例模式快速学习应用

    单例模式属于设计模式中最简单的一个模式,在实际应用中也非常广泛,但可能是受到各类教程的影响,看到很多实现方式仍然沿用Java的那一套,其实在.NET中可以用更简洁的实现方式. 一.知识点介绍 核心目标 ...

  6. P4-verilog实现mips单周期CPU

    最近对学习的掌控可能出现了问题,左支右绌,p2挂了,p2.p3.p4.p5每周在计组花的连续时间少了很多,学习到的东西也少了很多,流水线都还没真正开始写,和别人比落后了一大截,随笔自然就荒废了,我得尽 ...

  7. nyoj 47-过河问题 (贪心)

    47-过河问题 内存限制:64MB 时间限制:1000ms Special Judge: No accepted:2 submit:5 题目描述: 在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的 ...

  8. 【SSM】自定义属性配置的使用

    首先,建立xxx.properties 文件在resource文件夹中,此处我们自定义的配置文件是oj-config.properties 然后,在applicationContext.xml中注册这 ...

  9. 四 linuk常用命令 2. 权限管理命令

    一 权限管理命令chmod 所有者u 所属组g 其他人o 所有人a 所有者和root超级用户可以更改该权限 普通更改权限是不会改变子目录的权限的,要想改变用递归修改 useradd增加用户 目录的r和 ...

  10. Java多线程——多线程方法详解

    本系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线程的深入剖 ...