【问题描述】
阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机。打字机
上只有 28 个按键,分别印有 26 个小写英文字母和'B'、'P'两个字母。
经阿狸研究发现,这个打字机是这样工作的:
输入小写字母,打字机的一个凹槽中会加入这个字母(按 P 前凹槽中至
少有一个字母)。
按一下印有'B'的按键,打字机凹槽中最后一个字母会消失。
按一下印有'P'的按键,打字机会在纸上打印出凹槽中现有的所有字母并
换行,但凹槽中的字母不会消失(保证凹槽中至少有一个字母)。
例如,阿狸输入 aPaPBbP,纸上被打印的字符如下:
a
aa
ab
我们把纸上打印出来的字符串从 1 开始顺序编号,一直到 n。打字机有一个
非常有趣的功能,在打字机中暗藏一个带数字的小键盘,在小键盘上输入两个数
(x,y)(其中 1≤x,y≤n),打字机会显示第 x 个打印的字符串在第 y 个打印的字符串
中出现了多少次。
阿狸发现了这个功能以后很兴奋,他想写个程序完成同样的功能,你能帮助
他么?
【输入格式】
从文件 type.in 中读入数据。
输入的第一行包含一个字符串,按阿狸的输入顺序给出所有阿狸输入的字符。
第二行包含一个整数 m,表示询问个数。
接下来 m 行描述所有由小键盘输入的询问。其中第 i 行包含两个整数 x, y,
表示第 i 个询问为(x, y)。
【输出格式】
输出到文件 type.out 中。
输出 m 行,其中第 i 行包含一个整数,表示第 i 个询问的答案。
【样例输入】
aPaPBbP
3
1 2
1 3
2 3
【样例输出】
2
1
0
用失败指针反向建树的原因网上很多了,这里讲下后面处理的细节。
建完树只是找到了一个新思路,但是还是无法解决如何在以x串最后一个字符所在的节点为根的子树中找到包含多少个y串中的节点。如果你已经把每个节点所在的串标记了,怎么寻找呢?
再考虑,一棵树中以某节点为根的子树能满足那些性质呢?dfs序是连续的。所以我们可以先求出树的dfs序,确定以每个节点为根的子树所对应的区间。
然后呢?如果询问的是(x,y),那么我们就想办法把x串最后一个字符所在节点为根的子树中的y串上的节点独立出来。一个想法就是把它们赋成1,其他的点赋成0,然后就是树状数组或者线段树的区间求和操作了。
但是我们不可能对每个询问都清空树上面的标志在打上新的标志。所以就想:对于每次标记完的树都要尽可能地利用这些标记。显然。对于所有询问我们就可以把每一个y标记完的树,处理所有对应的(x[i],y)询问。
由于输入数据的特殊性。。。只要跟着输入的串在树上一步一步地走就可以了:
1.碰到B取消标志往上走。(trie树上。标志是映射到dfs序上的标志)
2.碰到P处理询问。
3.否则继续往下走并打上标记。(同1)
AC CODE
program noi_2011_day1_type;
var g1,g2,g3,next,last,en,tail:array[1..100000] of longint;
//============================================================================
procedure ins(x,y:longint);
begin
end;
//============================================================================
procedure insert(x,y,z:longint);
begin
end;
//============================================================================
procedure add(x,y:longint);
begin
end;
//============================================================================
function sum(x:longint):longint;
begin sum:=0;
end;
//============================================================================
procedure init;
var now,tmp:longint;
begin
end;
//============================================================================
procedure get_fail;
var g,h,i,j,now:longint;
begin
end;
//============================================================================
procedure dfs(x:longint);
var i:longint;
begin
end;
//============================================================================
procedure main;
var x,y,i,j,m,now,tmp:longint;
begin
end;
//============================================================================
begin
end.