傳送門
description
阿狸喜歡收藏各種稀奇古怪的東西,最近他淘到一台老式的打字機。打字機上只有28個按鍵,分別印有26個小寫英文本母和』b』、』p』兩個字母。
經阿狸研究發現,這個打字機是這樣工作的:
l 輸入小寫字母,打字機的乙個凹槽中會加入這個字母(這個字母加在凹槽的最後)。
l 按一下印有』b』的按鍵,打字機凹槽中最後乙個字母會消失。
l 按一下印有』p』的按鍵,打字機會在紙上列印出凹槽中現有的所有字母並換行,但凹槽中的字母不會消失。
例如,阿狸輸入apapbbp,紙上被列印的字元如下:
a aa
ab 我們把紙上列印出來的字串從1開始順序編號,一直到n。打字機有乙個非常有趣的功能,在打字機中暗藏乙個帶數字的小鍵盤,在小鍵盤上輸入兩個數(x,y)(其中1≤x,y≤n),打字機會顯示第x個列印的字串在第y個列印的字串中出現了多少次。
阿狸發現了這個功能以後很興奮,他想寫個程式完成同樣的功能,你能幫助他麼?
input
輸入的第一行包含乙個字串,按阿狸的輸入順序給出所有阿狸輸入的字元。
第二行包含乙個整數m,表示詢問個數。
接下來m行描述所有由小鍵盤輸入的詢問。其中第i行包含兩個整數x, y,表示第i個詢問為(x, y)。
output
輸出m行,其中第i行包含乙個整數,表示第i個詢問的答案。
sample input
apapbbp
3 1 2
1 3
2 3
sample output
2 1
0 hint
1<=n<=10^5
1<=m<=10^5
輸入總長<=10^5
source
trie
一道神奇的ac自動機(fail樹)的題目。
首先將ac自動機建立出來,然後構建失配指標。接下來是最重要的一步:構建fail樹。
fail樹是將ac自動機中的fail指標方向調轉構建成的樹,所以要在構建失配指標的時候就將邊建好。然後將fail樹構成dfs序。
我們將所有的問題讀入後按照y排序,然後再在ac自動機上跑一遍輸入的字串,當我們遇到乙個』p』就可以將所有y值為當前點所代表的字串的問題處理掉。
接下來就是如何求解出現次數的問題。由於dfs序有著美妙的性質:在某個節點的子樹中的節點一定出現在這個節點的入點和出點之間,所以我們可以在加入乙個點的時候對這個點+1,離開這個點的時候-1,統計答案的時候x的入點和出點之間的值就是答案。顯然可以用樹狀陣列來維護。
原理:如果x字串在y字串中出現過,那麼如果我們將ac自動機中y字串所有的點都跳一遍fail,這個過程中一定能跳到x字串上,因為x字串一定是y字串的某個字首的字尾。同樣地,因為fail樹是將所有的fail指標反向,所以在fail樹中,y字串一定在x字串的子樹中,剩餘的操作就是上一段中描述的了。
code:
#include
#include
#include
#include
using namespace std;
#define lowbit(x) x&(-x)
const int n=1e5+10;
struct ac
a[n];
struct query
}q[n];
struct edge
e[n<<1];
int t[n],head[n],pos[n];
char s[n];
int in[n],out[n];
int ans[n];
int tot,num,n,x,y,tot,len;
inline void add(int
x,int
y)inline void build()
}inline void makefail()
while(!q.empty())
a[a[tmp].ch[i]].fail=a[a[tmp].fail].ch[i];
add(a[a[tmp].fail].ch[i],a[tmp].ch[i]);
q.push(a[tmp].ch[i]);}}
}void dfs(int now,int fa)
inline void add(int now,int num)
inline int ask(int now)
inline void work()
else
if(s[i]=='b')
else
}int main()
BZOJ2434 NOI2011 阿狸的打字機
發現一種新的思路,以前從來沒有見過的,即ac自動機的fail樹。這一題我們先考慮暴力,從root往y的最後乙個點走,如果走到了x的末點,ans 如果通過fail指標走到了x的末點,ans 反過來考慮,從x的末點開始,如果當前點在y串或者通過反向的fail到了y串,ans 又發把fail反向之後得到的...
bzoj 2434 Noi2011 阿狸的打字機
time limit 10 sec memory limit 256 mb submit 3139 solved 1731 submit status discuss 阿狸喜歡收藏各種稀奇古怪的東西,最近他淘到一台老式的打字機。打字機上只有28個按鍵,分別印有26個小寫英文本母和 b p 兩個字母。...
BZOJ2434 NOI2011 阿狸的打字機
bzoj 洛谷我們先想一下最暴力是怎麼搞的 把 ac 自動機建好,每乙個節點,從 y 串的結尾節點往上跳它的父親,和普通的 ac 自動機一樣跳就好了 然而這個可以優化一下 我們將所有詢問離線 每個串統計一次其他串對它的貢獻 就可以有 70pts 了 70pts include include inc...