题目

两个\(log\)的树状数组套树剖?

我们对于给出的\(n\)个模式串建立\(AC\)自动机,之后对于每一个询问串直接丢上去匹配

如果这里是暴力的话,我们直接一路跳\(fail\)累加作为结束位置还没有被删除的点就好了

我们考虑一个快点的方式,树剖

把\(fail\)树建出来,直接在上面树剖维护就好了

由于只是单点修改,我们树状数组就好了

尽管是两个\(log\),但毕竟树剖和树状数组都是出了名的小常数,还是能跑过\(1e6\)的

代码

#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define lb(x) ((x)&(-x))
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=1e6+5;
struct E{int v,nxt;}e[maxn];
int n,m,cnt,__,num;
char S[maxn];
int c[maxn],dfn[maxn],sum[maxn],top[maxn],head[maxn];
int son[maxn][26],fa[maxn],pos[maxn],val[maxn],s[maxn];
inline void add_edge(int x,int y) {
e[++num].v=y;e[num].nxt=head[x];head[x]=num;
}
inline void ins(int o) {
scanf("%s",S+1);int len=strlen(S+1);
int now=0;
for(re int i=1;i<=len;i++) {
if(!son[now][S[i]-'a']) son[now][S[i]-'a']=++cnt;
now=son[now][S[i]-'a'];
}
pos[o]=now;
}
void dfs1(int x) {
int maxx=-1;s[x]=-1,sum[x]=1;
for(re int i=head[x];i;i=e[i].nxt) {
dfs1(e[i].v);
sum[x]+=sum[e[i].v];
if(sum[e[i].v]>maxx) maxx=sum[e[i].v],s[x]=e[i].v;
}
}
void dfs2(int x,int topf) {
top[x]=topf,dfn[x]=++__;
if(s[x]==-1) return;
dfs2(s[x],topf);
for(re int i=head[x];i;i=e[i].nxt)
if(s[x]!=e[i].v) dfs2(e[i].v,e[i].v);
}
inline void Build() {
std::queue<int> q;
for(re int i=0;i<26;i++) if(son[0][i]) q.push(son[0][i]);
while(!q.empty()) {
int k=q.front();q.pop();
for(re int i=0;i<26;i++)
if(son[k][i]) fa[son[k][i]]=son[fa[k]][i],q.push(son[k][i]);
else son[k][i]=son[fa[k]][i];
}
}
inline void add(int x,int v) {for(re int i=x;i<=cnt;i+=lb(i)) c[i]+=v;}
inline int ask(int x) {
int now=0;
for(re int i=x;i;i-=lb(i)) now+=c[i];
return now;
}
inline int query(int l,int r) {return ask(r)-ask(l-1);}
inline int Query(int x) {
int tot=0;
while(top[x]) {
tot+=query(dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
tot+=query(dfn[0],dfn[x]);
return tot;
}
int main() {
scanf("%d%d",&m,&n);
for(re int i=1;i<=n;i++) ins(i);
Build();
for(re int i=1;i<=cnt;i++) add_edge(fa[i],i);
dfs1(0);dfs2(0,0);cnt++;
for(re int i=1;i<=n;i++) val[i]=1,add(dfn[pos[i]],1);
while(m--) {
scanf("%s",S);int len=strlen(S);
if(S[0]=='+') {
int x=0;
for(re int i=1;i<len;i++) x=(x<<3)+(x<<1)+S[i]-48;
if(val[x]) continue;
add(dfn[pos[x]],1);val[x]=1;
}
if(S[0]=='-') {
int x=0;
for(re int i=1;i<len;i++) x=(x<<3)+(x<<1)+S[i]-48;
if(!val[x]) continue;
add(dfn[pos[x]],-1);val[x]=0;
}
if(S[0]=='?') {
int now=0;int ans=0;
for(re int i=1;i<len;i++) {
now=son[now][S[i]-'a'];
ans+=Query(now);
}
printf("%d\n",ans);
}
}
return 0;
}

【CF163E 】e-Government的更多相关文章

  1. 【NLP】Python NLTK获取文本语料和词汇资源

    Python NLTK 获取文本语料和词汇资源 作者:白宁超 2016年11月7日13:15:24 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的一种自然语言工具包,其收集 ...

  2. SCI&EI 英文PAPER投稿经验【转】

    英文投稿的一点经验[转载] From: http://chl033.woku.com/article/2893317.html 1. 首先一定要注意杂志的发表范围, 超出范围的千万别投,要不就是浪费时 ...

  3. 【独家】硅谷创业公司在中国常跌的五个坑|禾赛科技CEO李一帆柏林亚太周主题演讲

    [独家]硅谷创业公司在中国常跌的五个坑|禾赛科技CEO李一帆柏林亚太周主题演讲 李一帆 Xtecher特稿作者 关注  Xtecher推荐   演讲者:李一帆   翻译:晓娜   网址:www.xt ...

  4. 【236】◀▶IEW-Unit01

    Unit 1  Fast Food I.动名词的用法 Doing(V-ing) 核心思想:词性是名词,作用是动词 1. 名词 3)主语(句首) 保护环境是我们每个人的责任. Protecting th ...

  5. 【BFS】Help the Princess!

    题目描述 The people of a certain kingdom make a revolution against the bad government of the princess. T ...

  6. 【闭包】Pants On Fire

    Pants On Fire 题目描述 Donald and Mike are the leaders of the free world and haven’t yet (after half a y ...

  7. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  8. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  9. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

随机推荐

  1. js如何判断IE浏览器的版本包括IE11

    IE浏览器真是个坑:从ie6以及以前IE版本,简直就是垃圾,不按照Mozilla国际组织的标准来,乱搞.搞得兼容性很差:   <script type="text/javascript ...

  2. Android - Builder模式

    https://github.com/simple-android-framework-exchange/android_design_patterns_analysis/tree/master/bu ...

  3. 由Leetcode详解算法 之 动态规划(DP)

    因为最近一段时间接触了一些Leetcode上的题目,发现许多题目的解题思路相似,从中其实可以了解某类算法的一些应用场景. 这个随笔系列就是我尝试的分析总结,希望也能给大家一些启发. 动态规划的基本概念 ...

  4. tr,td高度不生效

    功能:表格内容较长,但是页面高度有限,超出显示滚动条 阻碍:给tr或者td加高度都不生效,不显示滚动条 解决方案:td中加div,设置高度和内容溢出时的样式 <table border='1' ...

  5. 浅谈脚本化css(一)

    读写css属性 每一个dom元素都有一个属性style,dom.style里面存放的这个元素的行间样式,我们可以通过这个属性来读写元素的行间样式. 注意: 1.我们碰到float这样的关键字属性的时候 ...

  6. PHP链接mysql 出现:由于目标计算机积极拒绝,无法连接

    1.PHP链接mysql 出现:由于目标计算机积极拒绝,无法连接 2.原因是mysql服务没有启动,图标呈现红色 3.启动服务即可,打开cmd,输入net start mysql即可 4.启动后,图标 ...

  7. js异步原理与 Promise

    一.Javascript的异步原理 javascript 是单线程语言,所以同一时间只执行一个运算.但有些方法是不能瞬间完成或不可预知何时完成的(如网络请求.settimeout等),为了让它们不对后 ...

  8. 异度之刃 Xenoblade 后感

    WII版重置的N3DS劣化版异度之刃终于通关了.在出色的自制系统的快乐NTR的帮助下,充分体验到了神作的剧情史诗感. 关于游戏的玩法系统,从现在来看8年前的游戏,缺点显而易见,特别是跑地图这回事,地图 ...

  9. 使用 Azure 门户创建 Linux 虚拟机

    可以通过 Azure 门户创建 Azure 虚拟机. 此方法提供一个基于浏览器的用户界面,用于创建和配置虚拟机和所有相关的资源. 本快速入门介绍了如何创建虚拟机并在 VM 上安装 webserver. ...

  10. js获取元素显示隐藏的当前状态

    js获取元素显示隐藏的当前状态 // CSS var display = $("."+cls).css("display"); if(display == &q ...