题意:

给出一个字典树,并告诉你若干串的结束位置。求第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]阿狸的打字机相关推荐

  1. [bzoj 2434][Noi2011]阿狸的打字机

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2434 [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory ...

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

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

  3. bzoj 2434 [Noi2011]阿狸的打字机(AC自动机+fail树+dfs序+树状数组)

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

  4. BZOJ 2434: [Noi2011]阿狸的打字机 ACAM+fail树

    title BZOJ 2434 LUOGU 2414 Description 打字机上只有 \(28\) 个按键,分别印有 \(26\) 个小写英文字母和 B.P 两个字母,是这样工作的: 输入小写字 ...

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

    Description 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: ·输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母 ...

  6. BZOJ 2434 NOI2011阿狸的打字机 AC自动机+树状数组

    如果你还没学AC自动机,请看这篇博客 Problem bzoj通道 洛谷通道 Solution 简单的说来,其实就是要快速求一个字符串在另一个字符串中出现了多少次.考虑构造AC自动机. 首先可以想到很 ...

  7. 2434: [Noi2011]阿狸的打字机

    2434: [Noi2011]阿狸的打字机 https://lydsy.com/JudgeOnline/problem.php?id=2434 分析: AC自动机. 查询x在y中出现了几次,就是查询y ...

  8. 【bzoj 2434】【codevs 1946】[Noi2011]阿狸的打字机(AC自动机)

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

  9. 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组

    [BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...

最新文章

  1. .net core 2.0 部署到centos 7生产环境
  2. 微信从原版到现在所有界面图片_微信突然宣布:现在能改微信号了,所有人都能改...
  3. matlab相机标定_【显微视界】基于视觉伺服的工业机器人系统研究(摄像机标定、手眼标定、目标单目定位)...
  4. 【51单片机快速入门指南】5:软件SPI
  5. arraylist可以存储不同类型吗_创新科技 - 不同防冻液可以混加吗
  6. 剑指offer.数值的整数次方
  7. watershed用法详解
  8. android 编译模块
  9. k邻近算法应用实例(一) 改进约会网站的配对效果
  10. 动作捕捉系统用于模仿学习
  11. bypy更换绑定的百度云盘账户
  12. LOJ#2538. 「PKUWC2018」Slay the Spire
  13. PHP开发的H5即时通讯聊天系统源码 带群聊 可封装APP
  14. 微信公众号学习与开发过程
  15. maven仓库类型说明 hosted/proxy/group
  16. 微信小程序+SpringBoot实现校园快递代收平台
  17. 基于zookeeper的瞬时节点实现分布式锁
  18. Service ‘MongoDB Server‘(MongoDB) failed to start.Verify that you have sufficient privileges to
  19. HTTP 重定向状态码是什么意思?
  20. MySQL数据库day01

热门文章

  1. android 切换字库,小米手机字库维修更换和EMMC字库编程烧写方法教程
  2. mysql seconds_behind_master_【MySQL】Seconds_Behind_Master的真正含义
  3. WebView Attack In Android : 解析第三方账号登录平台所存在的安全隐患
  4. 老罗的「聊天宝」是不是死了 ?
  5. 张驰课堂:六西格玛管理能保证零缺陷吗?
  6. 计算机进入安全模式,电脑安全模式怎么进入【图文教程】
  7. Ocata Neutron代码分析(六)——APIRouter的初始化(2)PluginAwareExtensionManager的初始化...
  8. 河道水尺水位监测系统 基于opencv
  9. slam十四讲,第五讲中相机坐标系,像素平面坐标系,世界坐标系,归一化坐标系总结
  10. 大牛_博客Java方面链接总结