ac自动机,bit,dfs序。

本文所有的stl都是因为自己懒得实现。

 

首先x在y里面出现,就意味y节点可以顺着fail回去。

反向建出一个fail数,然后搞出dfs序列。找出x对应的区间有多少个y。

再用离线操作,把每个y需要计算的x事先保存下来。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 100000 + 10; char s[maxn];
int a[maxn][26];
int g[maxn],v[maxn],next[maxn],eid;
int pos[maxn],cnt;
int fa[maxn],fail[maxn],L[maxn],R[maxn],query[maxn][3];
int m,n,u,dfn,vid;
vector<int> Q[maxn];
queue<int> q; struct BIT {
int a[maxn<<1],n; int lowbit(int x) {
return (x & -x);
} void add(int x,int d) {
//printf("c %d %d\n",x,d);
for(;x<=n;x+=lowbit(x)) a[x]+=d;
//printf("c");
} int query(int x) {
int res=0;
for(;x;x-=lowbit(x)) res+=a[x];
return res;
} void init(int _n) {
n=_n;
}
}bit; void addedge(int a,int b) {
v[eid]=b; next[eid]=g[a]; g[a]=eid++;
} void dfs(int u) {
L[u]=++dfn;
for(int i=g[u];~i;i=next[i]) dfs(v[i]);
R[u]=dfn;
} void get_trie() {
for(int i=0;i<26;i++) a[0][i]=1; int p=1,c;vid=1;
for(int i=0;i<n;i++) {
//printf("f[%d] = %d\n",i,p);
if(s[i]=='P') pos[++cnt]=p;
else if(s[i]=='B') p=fa[p];
else {
c=s[i]-'a';
if(!a[p][c])
a[p][c]=++vid,fa[vid]=p;
p=a[p][c];
}
//printf("f[%d] = %d\n",i,p);
}
} void debug(int p) {
} void get_fail() {
fail[1]=0;
q.push(1); while(!q.empty()) {
u=q.front();q.pop();
for(int k=0,p;k<26;k++)
if(a[u][k]) {
for(p=fail[u];p&&!a[p][k];p=fail[p]);
fail[a[u][k]]=a[p][k];
q.push(a[u][k]);
}
}
} void get_tree() {
for(int i=1;i<=vid;i++) addedge(fail[i],i);
dfs(1);
} void build() {
memset(g,-1,sizeof(g));
scanf("%s",s);n=strlen(s); get_trie();
//debug(1);
get_fail();
get_tree(); scanf("%d",&m);
for(int i=1;i<=m;i++) {
scanf("%d %d",&query[i][0],&query[i][1]);
query[i][0]=pos[query[i][0]];
query[i][1]=pos[query[i][1]];
Q[query[i][1]].push_back(i);
} } void solve() {
bit.init(n<<1);
int p=1;
for(int i=0;i<n;i++) {
//printf("s[i]=%c\n",s[i]);
if(s[i]=='P') for(int j=0;j<Q[p].size();j++)
query[Q[p][j]][2]=bit.query(R[query[Q[p][j]][0]])-bit.query(L[query[Q[p][j]][0]]-1);
else if(s[i]=='B') bit.add(L[p],-1),p=fa[p];
else p=a[p][s[i]-'a'],bit.add(L[p],1);
//printf(" %d\n",i);
} for(int i=1;i<=m;i++) printf("%d\n",query[i][2]);
} int main() {
build();
solve(); return 0;
}

2434: [Noi2011]阿狸的打字机的更多相关文章

  1. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

  2. BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

    一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...

  3. bzoj 2434 [Noi2011]阿狸的打字机 AC自动机

    [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4001  Solved: 2198[Submit][Status][D ...

  4. 2434: [Noi2011]阿狸的打字机 - BZOJ

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

  5. 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序

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

  6. 【刷题】BZOJ 2434 [Noi2011]阿狸的打字机

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

  7. BZOJ 2434: [Noi2011]阿狸的打字机 AC自动机+fail树+线段树

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

  8. bzoj 2434 [Noi2011]阿狸的打字机(fail树+离线处理+BIT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2434 [题意] 按照一定规则生成n个字符串,回答若干个询问:(x,y),问第x个字符串 ...

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

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

  10. bzoj 2434 [Noi2011]阿狸的打字机——AC自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2434 dfs AC自动机,走过的点权值+1,回溯的时候权值-1:走到询问的 y 串的节点,看 ...

随机推荐

  1. MySQL查询LIKE如何匹配下划线 通配符转义

    MySQL查询时使用LIKE匹配下划线,您会发现连查询“%A_B%”时会出现“%A B%”和“%AB%”也查询出来了,这是因为下划线也被当作特殊字符,做了任意匹配转换了,所以,要想匹配下划线,那么就需 ...

  2. 浏览器兼容CSS代码:按钮文字垂直居中(input button text vertical align)

    经过测试的浏览器:IE6, IE7, IE8, IE9, Firefox, Chrome, Safiri, Maxthon 按钮的HTML代码: <input id="btn_comm ...

  3. Eclipse编辑器基本设置

    1.添加行号 在边缘处右键 2.改字体 字体的一般配置 3.去掉拼写错误检查 4.Java代码风格 代码格式化 Ctrl + Shift + F 之后点击右边的New按钮,新建一个风格. 点击OK 上 ...

  4. couldnt resolve host mirrorlist.centos

     解决centos 6.3 yum安装软件时找不到镜像问题 [root@nagios-server ~]# yum update –y Loaded plugins: fastestmirror Lo ...

  5. iOS开发学习路线图

    很多初学iOS开发的人会经常问:“我想学iOS应该从何入手呢?”.作为一个做了2年多各种iOS开发的程序员,只想写写自己的一些心得体会,好和体验与不好的体验.写的不好,请多包涵.希望能起到抛砖引玉的作 ...

  6. 轻仿QQ音乐之音频歌词播放、锁屏歌词-b

    先上效果图 歌词播放界面 音乐播放界面 锁屏歌词界面 一. 项目概述 前面内容实在是太基础..只想看知识点的同学可以直接跳到第三部分的干货 项目播放的mp3文件及lrc文件均来自QQ音乐 本文主要主要 ...

  7. UINavigationBar导航栏相关设置

    设置导航颜色 [[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1] ...

  8. 信息化的“五观”与“N为”

    系统观:联系的总体的看 生产力工具观:人与工具关系 马克思政治经济学 辨证观:发展的看 技术观:第一生产力  改变生产生活(生存)方式 信息论观:“人”联网 控制论 工程观:群体合作的智力游戏论

  9. WCF获取客户端IP和端口

    //提供方法执行的上下文环境 OperationContext context = OperationContext.Current; //获取传进的消息属性 MessageProperties pr ...

  10. The 6th Zhejiang Provincial Collegiate Programming Contest->ProblemA:Second-price Auction

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3202 题意:拍卖东西,以第二高价的价格卖给出第一高价的人.输出最后获得东西 ...