CF 163E. e-Government ac自动机+fail树+树状数组
题目:
给出n个字符串,表示n个人名,有两种操作:
?string ,统计字符串string中出现的属于城市居民的次数。
+id,把编号为id的人变为城市居民,如果已经是忽略。
-id,把编号为id的人变为不是城市居民,如果已经不是的话忽略。
现有m个操作,对于?输出结果。
分析:
很容易想到建立ac自动机,+-操作倒简单,使用bool数组标记一下即可。对于每个询问,每次都沿着fail指针往上走,遇到了标记为城市居民的字符串时加1,否则继续往上走。
在这显然会TLE。很容易构造出以下数据:
a
aa
aaa
...
aaa...aaa
?aaa...aaa
考虑把fail指针反向,由于ac自动机的每个节点均有唯一的fail指针,若是沿着fail指针往上走,显然都会走到root,所以反向之后显然是一棵树,不妨称之为fail树。
fail树有什么特点呢?可以画个图试试,如果儿子节点出现过,那么他的祖先显然也会出现!因此,我们统计某个节点时,实际上就是统计在fail树中该节点到根的所有节点出现过的总次数。怎么统计?这不就是用dfs序维护树状数组吗?于是这题得以解决。每次寻找的时间复杂度为O(len*log)的级别。
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull; #define debug puts("here")
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)
#define pb push_back
#define RD(n) scanf("%d",&n)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
#define All(vec) vec.begin(),vec.end()
#define MP make_pair
#define PII pair<int,int>
#define PQ priority_queue
#define cmax(x,y) x = max(x,y)
#define cmin(x,y) x = min(x,y)
#define Clear(x) memset(x,0,sizeof(x))
//#pragma comment(linker, "/STACK:1024000000,1024000000") /******** program ********************/ const int MAXN = 1.5e6;
const int kind = 26; char s[MAXN];
bool use[MAXN]; struct BIT{
int c[2*MAXN];
inline void init(){
Clear(c);
}
inline int lowbit(int x){
return x & -x;
}
inline void update(int x,int y,int val){
modify(x,val);
modify(y,-val);
}
inline void modify(int x,int val){
if(x==0)return;
while(x<MAXN){
c[x] += val;
x += lowbit(x);
}
}
inline int ask(int x){
int ans = 0;
while(x>0){
ans += c[x];
x -= lowbit(x);
}
return ans;
}
}bit; struct AC{
int ch[MAXN][kind],fail[MAXN];
int tot;
vector<int> adj[MAXN];
int low[MAXN],dfn[MAXN],tol;
int at[MAXN]; inline void set(int x){
Clear(ch[x]);
fail[x] = 0;
} inline void init(){
rep(i,MAXN)
adj[i].clear();
set(1);
tot = 1;
tol = 0;
} inline int newNode(){
set(++tot);
return tot;
} inline int ind(char c){
return c-'a';
} inline void insert(int id){
int r = 1;
for(int i=0;s[i];i++){
int c = ind(s[i]);
if(ch[r][c]==0)
ch[r][c] = newNode();
r = ch[r][c];
}
at[id] = r;
} inline void build(){
queue<int> q;
q.push(1);
while(!q.empty()){
int r = q.front();
q.pop();
if(fail[r])
adj[ fail[r] ].pb(r);
rep(c,kind){
int x = ch[r][c];
if(!x)continue;
q.push(x); int y = fail[r];
while(y&&ch[y][c]==0)
y = fail[y];
fail[x] = y?ch[y][c]:1;
}
}
} void dfs(int x){
low[x] = ++tol;
foreach(i,adj[x])
dfs(adj[x][i]);
dfn[x] = tol;
} inline void run(){
int len = strlen(s)-1;
int ans = 0; int r = 1;
rep1(i,len){
int c = ind(s[i]);
while(r&&ch[r][c]==0)
r = fail[r];
if(r) r = ch[r][c];
else r = 1;
ans += bit.ask( low[r] );
} printf("%d\n",ans);
} }ac; void cc(int x,int val){
bit.update( ac.low[ ac.at[x] ],1+ac.dfn[ ac.at[x] ],val );
} int main(){ #ifndef ONLINE_JUDGE
freopen("sum.in","r",stdin);
//freopen("sum.out","w",stdout);
#endif int n,m;
while(cin>>m>>n){
ac.init();
bit.init(); rep1(i,n){
scanf("%s",s);
ac.insert(i);
use[i] = true;
} ac.build();
ac.dfs(1); rep1(x,n)
cc(x,1); int x;
while(m--){
scanf("%s",s);
if(s[0]=='?')
ac.run();
else{
sscanf(s+1,"%d",&x);
if(use[x]&&s[0]=='-'){
use[x] = 0;
cc(x,-1);
}else if(!use[x]&&s[0]=='+'){
use[x] = 1;
cc(x,1);
}
}
}
} return 0;
}
CF 163E. e-Government ac自动机+fail树+树状数组的更多相关文章
- CF G. Indie Album AC自动机+fail树+线段树
这个套路挺有意思的. 把 $trie$ 和 $fail$ 树都建出来,然后一起跑一跑就好了~ #include <queue> #include <cstdio> #inclu ...
- CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...
- AC自动机fail树上dfs序建线段树+动态memset清空
题意:http://acm.hdu.edu.cn/showproblem.php?pid=4117 思路:https://blog.csdn.net/u013306830/article/detail ...
- AC自动机——1 Trie树(字典树)介绍
AC自动机——1 Trie树(字典树)介绍 2013年10月15日 23:56:45 阅读数:2375 之前,我们介绍了Kmp算法,其实,他就是一种单模式匹配.当要检查一篇文章中是否有某些敏感词,这其 ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序
3881: [Coci2015]Divljak Time Limit: 20 Sec Memory Limit: 768 MBSubmit: 508 Solved: 158[Submit][Sta ...
- BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)
题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
- 【BZOJ-2434】阿狸的打字机 AC自动机 + Fail树 + DFS序 + 树状数组
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2022 Solved: 1158[Submit][Sta ...
随机推荐
- [转]在Arcmap中加载互联网地图资源的4种方法
转自http://blog.3snews.net/space.php?uid=6955280&do=blog&id=67981 前一段时间想在Arcmap中打开互联网地图中的地图数据, ...
- css ie7中overflow:hidden失效问题及解决方法
css兼容ie7: 做页面的时候用负边距居中的时候在IE7下面,父节点中的overflow:hiden失效的问题,查阅了一些资料,总结一下解决方法. 问题原因: 当父元素的直接子元素或者下级子元素的样 ...
- 【转】HTTP HEAD
原文出自:http://kb.cnblogs.com/page/92320/ HTTP(HyperTextTransferProtocol)即超文本传输协议,目前网页传输的的通用协议.HTTP协议采用 ...
- hdu 3681 Prison Break (TSP问题)
Prison Break Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- Codeforces Round #337 (Div. 2) A. Pasha and Stick 数学
A. Pasha and Stick 题目连接: http://www.codeforces.com/contest/610/problem/A Description Pasha has a woo ...
- C#缩放和裁剪图片
在GDI+中,缩放和剪裁可以看作同一个操作,无非就是原始区域的选择不同罢了.空口无凭,先看具体算法可能更好理解. using System; using System.Collections.Gene ...
- JBoss提供的常用的对称加密算法
package com.test.resteasy; import java.io.File; import java.net.MalformedURLException; import java.n ...
- ACdream 1115 Salmon And Cat (找规律&&打表)
题目链接:传送门 题意: 一个数被觉得是一个完美的数,仅仅要须要满足下面的两个条件之中的一个 1)x = 1 or 3 2)x = 2 + a*b + 2*a + 2*b; a.b都是完美的数. 分析 ...
- INDY idhttp Post用法
http://www.cnblogs.com/tk-del/archive/2013/05/10/3071541.html function Post(AURL: string; ASource: T ...
- 微信公共服务平台开发(.Net 的实现)7-------发送图文消息
之前我们讲过让微信发送给我们普通的文本信息,下面我们来看看如何发送图文信息,需要注意的是这里说的是,让微信发给我们,而不是我们拍个图片发给微信处理,我们上传图片在以后的章节介绍.下面是发送图文消息的函 ...