阿狸的打字机

70分 裸的AC自动机

program type2;
type
	node=record
		son:array[0..25]of longint;
		fa,fail,key,e:longint;
	end;
var	a:array[1..100005]of node; sto:longint=1;
	st:array[1..100005]of char; len:longint;
	q,head,next:array[1..100005]of longint;
	ans,lk:array[1..100005]of longint; n:longint;
	ask:array[1..100005,0..2]of longint;
	m:longint;
function getfail(const x:longint):longint;
var	k,w:longint;
begin
	if (x=1)then exit(0);
	k:=a[x].key;
	w:=a[a[x].fa].fail;
	while (w>0)and(a[w].son[k]=0) do w:=a[w].fail;
	if w=0 then exit(1) else exit(a[w].son[k]);
end;
procedure buildac;
var	h,t,x,i:longint;
begin
	h:=0;t:=1;q[1]:=1;
	while h<t do begin
		inc(h);x:=q[h];a[x].fail:=getfail(x);
		for i:=0 to 25 do if a[x].son[i]>0 then begin
			inc(t);q[t]:=a[x].son[i];
		end;
	end;
end;
procedure init;	var ch:char; w,k,i:longint;
begin
	w:=1;
	while not eoln do begin
		inc(len);read(ch);st[len]:=ch;
		case ch of
		'B':w:=a[w].fa;
		'P':begin inc(n); lk[n]:=w; a[w].e:=n; end;
		'a'..'z':begin
			k:=ord(ch)-ord('a');
			if a[w].son[k]=0 then begin
				inc(sto);a[w].son[k]:=sto;
				a[sto].fa:=w;a[sto].key:=k;
			end;
			w:=a[w].son[k];
			end;
		end;
	end;
	buildac;
	readln(m);
	for i:=1 to m do begin
		readln(ask[i][0],ask[i][1]);
		//ask[i][0]:=lk[ask[i][0]];
		ask[i][1]:=lk[ask[i][1]];
		next[i]:=head[ask[i][1]];
		head[ask[i][1]]:=i;
	end;
end;
procedure solve; var w,x,i,p:longint;ch:char;
begin
	w:=1;
	for i:=1 to len do begin
		ch:=st[i];
		case ch of
		'B':w:=a[w].fa;
		'P':begin
			fillchar(ans,sizeof(ans),0);
                        if head[w]=0 then continue;
                        p:=w;
			while w>1 do begin
				x:=w;
				while x>0 do begin
					if a[x].e>0 then inc(ans[a[x].e]);
					x:=a[x].fail;
				end;
				w:=a[w].fa;
			end;
                        w:=p;
			x:=head[w];
			while x<>0 do begin
				ask[x][2]:=ans[ask[x][0]];;
				x:=next[x];
			end;
		end;
		'a'..'z':w:=a[w].son[ord(ch)-ord('a')];
		end;
	end;
	for p:=1 to m do writeln(ask[p][2]);
end;
begin
	assign(input,'input.txt');reset(input);
	assign(output,'output.txt');rewrite(output);
	init;
	solve;
	close(input);close(output);
end.


满分程序(+dfs序优化)


program type2;
type
	node=record
		son:array[0..25]of longint;
		fa,fail,key,e:longint;
	end;
	heap=object
		s:array[1..100005]of longint;
		procedure add(x,k:longint);
		function sum(x:longint):longint;
	end;
	link=^Tnode;
	Tnode=record
		x:longint;
		next:link;
	end;
var	sto:longint=1;
procedure push(var x:link; const t:longint);
var 	p:link;
begin
	new(p); p^.x:=t; p^.next:=x; x:=p;
end;
procedure heap.add(x,k:longint);
begin
	while x<=sto do begin
		inc(s[x],k);
		inc(x,x and (-x));
	end;
end;
function heap.sum(x:longint):longint;
begin
	sum:=0;
	while x>0 do begin
		inc(sum,s[x]);
		dec(x,x and (-x));
	end;
end;

(*	definitions	for 	useful	objects		*)

var	a:array[0..100005]of node;
	st:array[1..100005]of char; len:longint;
	q,head,next:array[0..100005]of longint;
	ge:array[0..100005]of link;
	lk,ls,le:array[0..100005]of longint; n,tt:longint;
	ask:array[1..100005,0..2]of longint;
	m:longint; ans:Heap;
function getfail(const x:longint):longint;
var	k,w:longint;
begin
	if (x=1)then exit(0);
	k:=a[x].key;
	w:=a[a[x].fa].fail;
	while (w>0)and(a[w].son[k]=0) do w:=a[w].fail;
	if w=0 then exit(1) else exit(a[w].son[k]);
end;
procedure buildac;
var	h,t,x,i:longint;
begin
	h:=0;t:=1;q[1]:=1;
	while h<t do begin
		inc(h);x:=q[h];a[x].fail:=getfail(x);
		if x<>1 then push(ge[a[x].fail],x);
		for i:=0 to 25 do if a[x].son[i]>0 then begin
			inc(t);q[t]:=a[x].son[i];
		end;
	end;
end;
procedure DFS(const x:longint); var p:link;
begin
	inc(tt);ls[x]:=tt;
	p:=ge[x];while p<>nil do begin
		DFS(p^.x);p:=p^.next;
	end;le[x]:=tt;
end;
procedure init;	var ch:char; w,k,i:longint;
begin
	w:=1;
	while not eoln do begin
		inc(len);read(ch);st[len]:=ch;
		case ch of
		'B':w:=a[w].fa;
		'P':begin inc(n); lk[n]:=w; a[w].e:=n; end;
		'a'..'z':begin
			k:=ord(ch)-ord('a');
			if a[w].son[k]=0 then begin
				inc(sto);a[w].son[k]:=sto;
				a[sto].fa:=w;a[sto].key:=k;
			end;
			w:=a[w].son[k];
			end;
		end;
	end;
	buildac;
	DFS(1);
	readln(m);
	for i:=1 to m do begin
		readln(ask[i][0],ask[i][1]);
		ask[i][0]:=lk[ask[i][0]];
		ask[i][1]:=lk[ask[i][1]];
		next[i]:=head[ask[i][1]];
		head[ask[i][1]]:=i;
	end;
end;
procedure solve; var w,x,i:longint;ch:char;
begin
	w:=1;
	for i:=1 to len do begin
		ch:=st[i];
		case ch of
		'B':begin
			ans.add(ls[w],-1);
			w:=a[w].fa;
		end;
		'P':begin
			x:=head[w];
			while x<>0 do begin
				ask[x][2]:=ans.sum(le[ask[x][0]])-ans.sum(ls[ask[x][0]]-1);
				x:=next[x];
			end;
		end;
		'a'..'z':begin w:=a[w].son[ord(ch)-ord('a')]; ans.add(ls[w],1); end;
		end;
	end;
	for i:=1 to m do writeln(ask[i][2]);
end;
begin
	assign(input,'input.txt');reset(input);
	assign(output,'output.txt');rewrite(output);
	init;
	solve;
	close(input);close(output);
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值