【bzoj2434】: [Noi2011]阿狸的打字机

x串在y串上的匹配次数就是y在自动机所有节点上能够通过fail走到x最后一个节点的个数

(就是y串任意一个前缀的后缀能匹配到x的个数)和【bzoj3172】: [Tjoi2013]单词差不多

把fail指针反向就是x的子树的和 用dfs序+BIT就可以维护了

如果把y串一个个走自动机显然会TLE

但是如果按照打字顺序模拟'a'-'z' 在trie上前进一格单点+1 'B'在trie上后退一格单点-1

那么显然可以得到所有y串但只需要O(n)

然后离线处理一下就好了

 /* http://www.cnblogs.com/karl07/ */
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=1e5+;
char s[N];
struct edge{ int next,to; edge(int next=,int to=) : next(next),to(to){}; }e[N];
struct trie{ int th; trie *next[],*fail,*fa; }t[N],*NEW=t,*root=t,*q[N],*now=t,*sth[N];
struct Query{int x,y,id;}Q[N];
int ade,l=,r=,df,n,c2;
int first[N],st[N],ed[N],BIT[N*],ans[N];
#define pn p->next[i]
#define pnf p->next[i]->fail
#define lowbit(x) (x&-x) void modify(int x,int m){
for (;x<=N;x+=lowbit(x)) BIT[x]+=m;
} int query(int l,int r){
int a1=,a2=;
for (;r;r-=lowbit(r)) a1+=BIT[r];
for (l--;l;l-=lowbit(l)) a2+=BIT[l];
return a1-a2;
} void addedge(int x,int y){
e[++ade]=edge(first[x],y),first[x]=ade;
} trie *new1(trie *p){ NEW++; NEW->fa=p; return NEW; } trie *insert(trie *p,int i,int x){
if (!pn) pn=new1(p);
if (x!=) modify(st[pn->th],);
return pn;
} trie *remove(trie *p,int x){
if (x!=) modify(st[p->th],-);
return p->fa;
} void build_fail(){
trie *p=q[]=root;
root->th=;
for (int i=;i<;i++) if (pn) q[++r]=pn,pnf=root,pn->th=r,addedge(,pn->th);
while (l<r){
p=q[++l];
for (int i=;i<;i++){
if (pn){
q[++r]=pn,pn->th=r;
for (pnf=p->fail ; pnf!=root && !pnf->next[i] ; pnf=pnf->fail);
if (pnf->next[i]) pnf=pnf->next[i];
addedge(pnf->th,pn->th);
}
}
}
} void dfs(int p){
st[p]=++df;
for (int x=first[p];x;x=e[x].next){
if (e[x].to) dfs(e[x].to);
}
ed[p]=df;
} bool oper(Query a, Query b){return a.y<b.y;} int main(){
scanf("%s",s);
scanf("%d",&n);
for (int i=;i<=n;i++) {
scanf("%d%d",&Q[i].x,&Q[i].y);
Q[i].id=i;
}
sort(Q+,Q++n,oper);
for (int l=strlen(s),i=;i<l;i++){
if (s[i]>='a' && s[i]<='z') now=insert(now,s[i]-'a',);
if (s[i]=='B') now=remove(now,);
if (s[i]=='P') sth[++c2]=now;
}
build_fail();
dfs();
now=root;
for (int i=,j=;i<=n;i++){
while (sth[Q[i].y]!=now) {
if (s[j]>='a' && s[j]<='z') now=insert(now,s[j]-'a',);
if (s[j]=='B') now=remove(now,);
j++;
}
ans[Q[i].id]=query(st[sth[Q[i].x]->th],ed[sth[Q[i].x]->th]);
}
for (int i=;i<=n;i++) printf("%d\n",ans[i]);
return ;
}

竟然过了样例一次就A了。。

【bzoj2434】: [Noi2011]阿狸的打字机 字符串-AC自动机-BIT的更多相关文章

  1. BZOJ2434 [Noi2011]阿狸的打字机 【AC自动机 + fail树 + 树状数组】

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 3610  Solved: 1960 [Submit][S ...

  2. BZOJ2434: [NOI2011]阿狸的打字机(AC自动机+dfs序+树状数组)

    [NOI2011]阿狸的打字机 题目链接:https://www.luogu.org/problemnew/show/P2414 题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. ...

  3. BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)

    题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...

  4. 【BZOJ2434】阿狸的打字机(AC自动机,树状数组)

    [BZOJ2434]阿狸的打字机(AC自动机,树状数组) 先写个暴力: 每次打印出字符串后,就插入到\(Trie\)树中 搞完后直接搭\(AC\)自动机 看一看匹配是怎么样的: 每次沿着\(AC\)自 ...

  5. BZOJ 2434 [Noi2011]阿狸的打字机(AC自动机)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2434 [题目大意] 给出一个打印的过程,'a'-'z'表示输入字母,P表示打印该字符串 ...

  6. 洛谷P2414 [NOI2011]阿狸的打字机(AC自动机)

    传送门 考虑一下,如果串B在串A中出现过,那么A的fail指针必定直接或间接指向B 那么我们可以把fail树建起来,那么就变成B代表的节点的子树里有多少节点属于A 然后这就是一个序列统计问题,直接用d ...

  7. 【BZOJ2434】【NOI2011】阿狸的打字机(AC自动机,树状数组)

    [BZOJ2434]阿狸的打字机(AC自动机,树状数组) 先写个暴力: 每次打印出字符串后,就插入到\(Trie\)树中 搞完后直接搭\(AC\)自动机 看一看匹配是怎么样的: 每次沿着\(AC\)自 ...

  8. BZOJ_2434_[NOI2011]_阿狸的打字机_(AC自动机+dfs序+树状数组)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2434 给出\(n\)个字符串,\(m\)个询问,对于第\(i\)个询问,求第\(x_i\)个字 ...

  9. BZOJ2434: [Noi2011]阿狸的打字机(AC自动机 树状数组)

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4140  Solved: 2276[Submit][Status][Discuss] Descript ...

随机推荐

  1. app中使用微信分享注意事项

    1.  在微信公众平台开通一个微信公众号,https://mp.weixin.qq.com 2.  将自己制作好的已签名的app安装到手机上 3.  下载微信开放平台获取应用签名的apk--- gen ...

  2. vBulletin 5.x 版本通杀远程代码执行漏洞复现

    漏洞介绍 vBulletin中存在一个文件包含问题,可使恶意访问者包含来自 vBulletin 服务器的文件并且执行任意 PHP 代码.未经验证的恶意访问者可通过向index.php发出包含 rout ...

  3. 2015.1.4 判断鼠标点击DataGridView的第几行还是空白处

    public int GetRowIndexAt(int mouseLocation_Y) { if (dvaw.FirstDisplayedScrollingRowIndex < 0) { r ...

  4. 2015.12.24(圣诞节) 解决Oralce数据库将具有相同属性的多行合并为一行的简单方法多年想要wmsys.wm_concat

    用到Oralce10g以后增加的函数wmsys.wm_concat 例如这张表的有两个字段,要按airport_id合并成两行可用sql语句 select airport_id,   wmsys.wm ...

  5. 如何Catalog磁带库中的备份集

    在NBU备份的环境中,可以使用以下步骤来Catalog磁带库中的备份集. 1. 查找需要Catalog的备份集名称 可以使用两种方法查找Oracle备份集. 方法一是使用RMAN的list命令查找,例 ...

  6. oracle常用函数总结(一)

    最近在读数据库存储过程,或者在xml里写sql时用到数据库函数,笔者觉得有必要总结一下,当然有的函数笔者也很懵逼,不过可以问度娘啊!好了!开始正题. )s from dual;--1 若nvl第一个参 ...

  7. vs中ffmpeg release版本崩溃问题(转)

    vs2010 win7 下开发视频服务器,用到ffmpeg,debug版本运行正常,切换到release时,出现"0x00905a4d 处未处理的异常: 0xC0000005: 读取位置 0 ...

  8. android手机分辨率的一些说明

    Android上常见度量单位 px(像素):屏幕上的点,绝对长度,与硬件相关 in(英寸):长度单位 mm(毫米):长度单位 pt(磅):1/72英寸,point dp(与密度无关的像素):一种基于屏 ...

  9. 学习CSS的思路(转)

    两周之前写过该系列的第一篇,其实当时只是一个想法,这段时间迟迟未更新,是在思考一个解决过程.现在初有成效,就开更吧. 1. 一个段子 开题不必太严肃,写博客也不像写书,像聊天似的写东西是最好的表达方式 ...

  10. JavaScript问题01 js代码放在header和body的区别

    1 body和header中JavaScript执行的时机 1.1 header中 放在header中的javascript代码会进行预加载(即:在页面加载之前就会进行),所以需调用才执行的脚本或事件 ...