博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj2434: [Noi2011]阿狸的打字机
阅读量:4965 次
发布时间:2019-06-12

本文共 2207 字,大约阅读时间需要 7 分钟。

可以说也是很迷了。最近写的字符串的题都很迷。。

首先看到路牌先写板子AC机,然后迷

然后???

回忆一下fail的定义:fail[i]到根形成的字符串是i到根形成的字符串的后缀。

那么大力跳fail硬搞

那么题目询问就变成了求在第y个字符串的那条路径上,有多少个节点fail指向的是第x个字符串的最后一个节点。

根据题解考虑离线搞。

排序一下,这样我们就可以把询问相同y字符串放在一起做。

还是不会做。先把后缀树建出来吧。

诶好像在底部的点都可以对上层的点作出贡献诶,也就是说假如y中的一个点的fail指向x的结尾,那么这个点肯定在x的结尾点的子树里面,那是不是dfs序一下搞个树状数组求答案就行了?

那就再for一次原串,遇到字符就给它+1,删就-1,到了P就看下现在是第几个字符串,这个时候的树状数组就已经把当前字符串的值记录下来了,找到所对应的询问的x串结尾在哪,把它子树的值求出来就行了。

#include
#include
#include
#include
#include
#include
using namespace std;char ss[110000];int slen;int cnt,chuan[110000];struct Trie{ int w[30],fa,fail;}tr[510000];int trlen;void insert(){ scanf("%s",ss+1);slen=strlen(ss+1); trlen=0;cnt=0; int now=0; for(int i=1;i<=slen;i++) { if(ss[i]=='B')now=tr[now].fa; else if(ss[i]=='P')chuan[++cnt]=now; else { int x=ss[i]-'a'+1; if(tr[now].w[x]==0) tr[now].w[x]=++trlen, tr[trlen].fa=now; now=tr[now].w[x]; } }}int list[510000];void bfs(){ int head=1,tail=2;list[head]=0; while(head!=tail) { int now=list[head]; for(int x=1;x<=26;x++) { int son=tr[now].w[x]; if(son!=0) { if(now==0)tr[son].fail=0; else { int p=tr[now].fail; while(p!=0&&tr[p].w[x]==0)p=tr[p].fail; tr[son].fail=tr[p].w[x]; } list[tail]=son; tail++;if(tail==505000)tail=1; } } head++;if(head==505000)head=1; }}//-----------------AC_machine------------------------struct node{ int x,y,next;}a[510000];int len,last[510000];void ins(int x,int y){ len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len;}int z,l[510000],r[510000];void get_dfs(int x){ l[x]=++z; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; get_dfs(y); } r[x]=z;}void makefailtree(){ len=0;memset(last,0,sizeof(last)); for(int i=1;i<=trlen;i++)ins(tr[i].fail,i); z=0;get_dfs(0);}//-------------make tree and get dfs---------------------int s[510000];int lowbit(int x){ return x&-x;}void change(int x,int k){ while(x<=z) { s[x]+=k; x+=lowbit(x); }}int getsum(int x){ int ret=0; while(x>=1) { ret+=s[x]; x-=lowbit(x); } return ret;}//--------------bit-----------------------struct query{ int x,y,id;}q[110000];int tip;bool cmp(query n1,query n2){ return n1.y

 

转载于:https://www.cnblogs.com/AKCqhzdy/p/8681101.html

你可能感兴趣的文章
2018 Multi-University Training Contest 10 - Count
查看>>
HDU6203 ping ping ping
查看>>
《人人都是产品经理》书籍目录
查看>>
如何在git bash中运行mysql
查看>>
OO第三阶段总结
查看>>
构建之法阅读笔记02
查看>>
DataTable和 DataRow的 区别与联系
查看>>
检索COM 类工厂中CLSID 为 {00024500-0000-0000-C000-000000000046}的组件时失败
查看>>
mysql数据库中数据类型
查看>>
Fireworks基本使用
查看>>
Linux 标准 I/O 库
查看>>
.net Tuple特性
查看>>
Java基础常见英语词汇
查看>>
nginx启动、关闭命令、重启nginx报错open() "/var/run/nginx/nginx.pid" failed
查看>>
BZOJ 3097 Hash Killer I
查看>>
UINavigationController的视图层理关系
查看>>
html阴影效果怎么做,css 内阴影怎么做
查看>>
宏观经济
查看>>
综合练习:词频统计
查看>>
BZOJ1026: [SCOI2009]windy数
查看>>