bzoj 2434: [Noi2011]阿狸的打字机
题意:
给出一个字典树,并告诉你若干串的结束位置。求第x个串在第y个串的出现次数。
题解:
不难的AC自动机+不难的主席树。
首先对于字典树建AC自动机,那么对于一个串S,假如能在这个串的结尾点不断跳fail跳到S1的结尾点的话,就说明S的其中一个后缀是S1。那么我们可以枚举串y的前缀,假如这个前缀的后缀是x的话,ans++。即该前缀的结尾点是x结尾点在fail树上的子节点。
我们对fail树dfs序,问题就成了y串在字典树上的路径有多少个点是x结尾点的子节点,也就是在x的子树的dfs序范围内,自然想到主席树。好像有树状数组做法的
code:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
struct trnode{int a[27],fail,fa,tail;
}tr[100010];int tail[100010],ROOT=1,now=1,tot=1,ys[100010],z=0,n,root[100010];
struct TRnode{int lc,rc,c;
}TR[2500010];
struct node{int y,next;
}a[100010];int last[100010],len=0;
void ins(int x,int y)
{a[++len].y=y;a[len].next=last[x];last[x]=len;
}
char ch;
int insert(int x,int c)
{if(!tr[x].a[c]){tr[x].a[c]=++tot;tr[tot].fa=x;}return tr[x].a[c];
}
queue<int> q;
void make_fail()
{q.push(ROOT);while(!q.empty()){int x=q.front();q.pop();for(int i=0;i<26;i++){if(!tr[x].a[i]) continue;if(x==ROOT) tr[tr[x].a[i]].fail=ROOT;else{int j=tr[x].fail;while(j!=ROOT&&!tr[j].a[i]) j=tr[j].fail;tr[tr[x].a[i]].fail=tr[j].a[i];}q.push(tr[x].a[i]);}}
}
void dfs(int x)
{ys[x]=tr[x].tail=++z;for(int i=last[x];i;i=a[i].next){int y=a[i].y;dfs(y);tr[x].tail=tr[y].tail;}
}
void update(int &x,int froot,int l,int r,int k,int c)
{x=++tot;TR[x].lc=TR[froot].lc;TR[x].rc=TR[froot].rc;TR[x].c=TR[froot].c;if(l==r){TR[x].c+=c;return;}int mid=(l+r)/2;if(k<=mid) update(TR[x].lc,TR[froot].lc,l,mid,k,c);else update(TR[x].rc,TR[froot].rc,mid+1,r,k,c);TR[x].c=TR[TR[x].lc].c+TR[TR[x].rc].c;
}
int findans(int x,int l,int r,int fl,int fr)
{if(!x) return 0;if(l==fl&&r==fr) return TR[x].c;int mid=(l+r)/2;if(fr<=mid) return findans(TR[x].lc,l,mid,fl,fr);if(fl>mid) return findans(TR[x].rc,mid+1,r,fl,fr);return findans(TR[x].lc,l,mid,fl,mid)+findans(TR[x].rc,mid+1,r,mid+1,fr);
}
void bt(int x)
{update(root[x],root[tr[x].fa],1,n,ys[x],1);for(int i=0;i<26;i++)if(tr[x].a[i]!=0) bt(tr[x].a[i]);
}
int main()
{tail[1]=ROOT;for(int i=0;i<26;i++) tr[ROOT].a[i]=++tot,tr[tot].fa=ROOT;while(scanf("%c",&ch)){if(ch=='\n') break;else if(ch=='P') now++,tail[now]=tail[now-1];else if(ch=='B') tail[now]=tr[tail[now]].fa;else tail[now]=insert(tail[now],ch-'a');}make_fail();for(int i=2;i<=tot;i++) ins(tr[i].fail,i);n=tot;tot=0;dfs(1);bt(ROOT);int T;scanf("%d",&T);while(T--){int x,y;scanf("%d %d",&x,&y);if(x>=now||y>=now){printf("0\n");continue;}x=tail[x];y=tail[y];int ans=0;printf("%d\n",findans(root[y],1,n,ys[x],tr[x].tail));}
}
数据生成器:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<ctime>
using namespace std;
int main()
{srand(time(0));int n=rand()%1000+1,num=0,t=1,k=0;while(t<=n){int tmp=rand()%5;if(tmp==0){if(num==0) continue;else printf("B"),num--,t++;}else if(tmp==1){if(num==0) continue;printf("P"),t++,k++;}else printf("%c",rand()%2+'a'),num++,t++;}printf("\n");int m=rand()%30+1;printf("%d\n",m);if(!k) k=1;for(int i=1;i<=m;i++){int x=rand()%k+1,y=rand()%k+1;printf("%d %d\n",x,y);}
}
bzoj 2434: [Noi2011]阿狸的打字机相关推荐
- [bzoj 2434][Noi2011]阿狸的打字机
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2434 [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 2545 Solved: 1419 [Submit][S ...
- bzoj 2434 [Noi2011]阿狸的打字机(AC自动机+fail树+dfs序+树状数组)
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 3521 Solved: 1913 [Submit][S ...
- BZOJ 2434: [Noi2011]阿狸的打字机 ACAM+fail树
title BZOJ 2434 LUOGU 2414 Description 打字机上只有 \(28\) 个按键,分别印有 \(26\) 个小写英文字母和 B.P 两个字母,是这样工作的: 输入小写字 ...
- [BZOJ 2434][Noi2011]阿狸的打字机(AC自动机+树状数组+dfs序)
Description 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: ·输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母 ...
- BZOJ 2434 NOI2011阿狸的打字机 AC自动机+树状数组
如果你还没学AC自动机,请看这篇博客 Problem bzoj通道 洛谷通道 Solution 简单的说来,其实就是要快速求一个字符串在另一个字符串中出现了多少次.考虑构造AC自动机. 首先可以想到很 ...
- 2434: [Noi2011]阿狸的打字机
2434: [Noi2011]阿狸的打字机 https://lydsy.com/JudgeOnline/problem.php?id=2434 分析: AC自动机. 查询x在y中出现了几次,就是查询y ...
- 【bzoj 2434】【codevs 1946】[Noi2011]阿狸的打字机(AC自动机)
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 2477 Solved: 1382 [Submit][S ...
- 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组
[BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...
最新文章
- .net core 2.0 部署到centos 7生产环境
- 微信从原版到现在所有界面图片_微信突然宣布:现在能改微信号了,所有人都能改...
- matlab相机标定_【显微视界】基于视觉伺服的工业机器人系统研究(摄像机标定、手眼标定、目标单目定位)...
- 【51单片机快速入门指南】5:软件SPI
- arraylist可以存储不同类型吗_创新科技 - 不同防冻液可以混加吗
- 剑指offer.数值的整数次方
- watershed用法详解
- android 编译模块
- k邻近算法应用实例(一) 改进约会网站的配对效果
- 动作捕捉系统用于模仿学习
- bypy更换绑定的百度云盘账户
- LOJ#2538. 「PKUWC2018」Slay the Spire
- PHP开发的H5即时通讯聊天系统源码 带群聊 可封装APP
- 微信公众号学习与开发过程
- maven仓库类型说明 hosted/proxy/group
- 微信小程序+SpringBoot实现校园快递代收平台
- 基于zookeeper的瞬时节点实现分布式锁
- Service ‘MongoDB Server‘(MongoDB) failed to start.Verify that you have sufficient privileges to
- HTTP 重定向状态码是什么意思?
- MySQL数据库day01
热门文章
- android 切换字库,小米手机字库维修更换和EMMC字库编程烧写方法教程
- mysql seconds_behind_master_【MySQL】Seconds_Behind_Master的真正含义
- WebView Attack In Android : 解析第三方账号登录平台所存在的安全隐患
- 老罗的「聊天宝」是不是死了 ?
- 张驰课堂:六西格玛管理能保证零缺陷吗?
- 计算机进入安全模式,电脑安全模式怎么进入【图文教程】
- Ocata Neutron代码分析(六)——APIRouter的初始化(2)PluginAwareExtensionManager的初始化...
- 河道水尺水位监测系统 基于opencv
- slam十四讲,第五讲中相机坐标系,像素平面坐标系,世界坐标系,归一化坐标系总结
- 大牛_博客Java方面链接总结