阿狸的打字机

原创 2016年08月28日 15:45:46
orzzw的超短写法.
终于明白fail树是什么意思了-.-
写完交到gfoj无故re,好在cv和bz上都过了.
#include <cstdio>
using namespace std;
const int N=100050;
struct edge {  
	int u,v; edge *nxt;  
	edge (int u,int v,edge *pre): u(u),v(v){nxt=pre;}  
};  
edge *he[N],*qe[N];
int ans[N],ent[N],out[N],cnt;
int fa[N],fail[N],tot;
int id[N],to[N][26],cot;
int q[N];
struct xdt {
	#define mid ((l+r)>>1)
	int a[8*N];
	void add(int t,int l,int r,int x,int k) {
		a[t]+=k;
		if (l==r) return ;
		if (x<=mid) add(t*2,l,mid,x,k); else add(t*2+1,mid+1,r,x,k);
	}
	int  ask(int t,int l,int r,int x,int y) {
		if (x<=l && r<=y) return a[t];
		int ans=0;
		if (x<=mid) ans+=ask(t*2,l,mid,x,y);
		if (y>mid)  ans+=ask(t*2+1,mid+1,r,x,y);
		return ans;
	}
}xdt;
void dfs(int u) {
	ent[u]=++cnt;
	for (edge *i=he[u];i;i=i->nxt) dfs(i->v);
	out[u]=++cnt;
}
void DFS(int u) {
	xdt.add(1,1,cnt,ent[u],1);
	for (edge *i=qe[u];i;i=i->nxt) 
		ans[i->u]=xdt.ask(1,1,cnt,ent[i->v],out[i->v]);
	for (int j=0;j<26;j++) if (to[u][j]) DFS(to[u][j]);
	xdt.add(1,1,cnt,ent[u],-1);
} 
int main() {
	#define nxt to[nw][ch-'a']
	int i,j,n,x,y,l,r,nw; char ch;
	while ((ch=getchar())!='P' && ch!='B' && (ch<'a'||ch>'z')) ;
	for (i=0;i<26;i++) to[0][i]=1;
	for (tot=nw=1;ch=='P' || ch=='B' || (ch>='a' && ch<='z');ch=getchar()) {
		if (ch=='P') id[++cot]=nw; else
		if (ch=='B') nw=fa[nw]; else
		fa[nxt?nxt:nxt=++tot]=nw,nw=nxt;
	}
	for (l=r=q[1]=1;l<=r;l++) 
		for (nw=q[l],i=0;i<26;i++) if (to[nw][i]) {
			for (j=fail[nw];!to[j][i];j=fail[j]) ;
			fail[q[++r]=to[nw][i]]=to[j][i];
		} 
	for (i=1;i<=tot;i++) he[fail[i]]=new edge(fail[i],i,he[fail[i]]);
	for (scanf("%d",&n),i=1;i<=n;i++) {
		scanf("%d%d",&x,&y); x=id[x],y=id[y];
		qe[y]=new edge(i,x,qe[y]);
	}
	dfs(1);
	DFS(1);
	for (i=1;i<=n;i++) printf("%d\n",ans[i]);
} 


版权声明:本文为博主原创文章,未经博主允许不得转载。

阿狸的打字机 NOI2011

AC自动机是肯定的了,但关键是如何完成快速匹配,如果像普通的自动机那样在每个状态都通过fail转移累加的话肯定会超时的,所以需要一种新的方法,那就是维护fail逆向指针树的dfs序列,听上去挺麻烦的,...
  • gyarenas
  • gyarenas
  • 2013年07月06日 21:12
  • 2293

bzoj2434【NOI2011】阿狸的打字机

AC自动机+树状数组+DFS序
  • AaronGZK
  • AaronGZK
  • 2016年05月25日 00:14
  • 2625

【BZOJ2434】【NOI2011】阿狸的打字机 AC自动机

这是一道神题。 首先我们需要建立AC自动机,然后再建个Fail树,之后发现     如果询问a串在b串中出现了几次,那么只需要看b串在AC自动机上所有的节点中有多少个节点,在a串的结束节点在Fai...
  • Vmurder
  • Vmurder
  • 2015年01月19日 16:48
  • 1630

BZOJ 2434([Noi2011]阿狸的打字机-AC自动机-Fail树)

2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 544  Solved: 300 [Submit][...
  • nike0good
  • nike0good
  • 2013年05月21日 17:54
  • 1630

【AC自动机-fail树+离线+DFS序+树状数组】BZOJ2434(Noi2011)[阿狸的打字机]题解

题目概述有一台打字机,可以: 在字符串末尾插入一个小写字母。 删除字符串末尾的一个小写字母。 输出当前字符串。 还有 mm 个询问,每个询问 x,yx,y 表示求第 xx 个输出的字符串在第 yy 个...
  • zzkksunboy
  • zzkksunboy
  • 2017年08月08日 11:54
  • 285

阿狸的打字机(bzoj2434,codevs1946,洛谷2414)

1.分析 朴素的算法是把所有字符串处理出来后对于每个询问进行一次kmp,然并卵,肯定超时。 因为有很多字符串,我们可以考虑建立一个AC自动机。这样我们又有了一种思路,假如顺着某个节点的fail指针...
  • litble
  • litble
  • 2017年04月20日 18:50
  • 264

阿狸的打字机 NOI2011

AC自动机是肯定的了,但关键是如何完成快速匹配,如果像普通的自动机那样在每个状态都通过fail转移累加的话肯定会超时的,所以需要一种新的方法,那就是维护fail逆向指针树的dfs序列,听上去挺麻烦的,...
  • gyarenas
  • gyarenas
  • 2013年07月06日 21:12
  • 2293

NOI2011阿狸的打字机

题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机。题目描述 打字机上只有28个按键,分别印有26个小写英文字母和’B’、’P’两个字母。经阿狸研究发现,这个打字机是这样工作的:...
  • Frods
  • Frods
  • 2017年03月31日 21:22
  • 219

【Bzoj 2434】[NOI 2011] 阿狸的打字机

Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机。 打字机上只有28个按键,分别印有26个小写英文字母和'B'、'P'两个字母。 经阿狸研究发现,这个打字...
  • Heristor
  • Heristor
  • 2016年01月23日 23:21
  • 185

[省选前题目整理][BZOJ 2434][NOI 2011]阿狸的打字机(AC自动机+fail树+DFS序+树状数组)

题目链接http://www.lydsy.com/JudgeOnline/problem.php?id=2434思路将每个打印出来的串插入AC自动机后可以发现,a串在b串中的出现次数,就是在AC自动机...
  • qpswwww
  • qpswwww
  • 2015年04月02日 15:55
  • 422
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:阿狸的打字机
举报原因:
原因补充:

(最多只允许输入30个字)