bzoj2434 Noi2011 阿狸的打字機

2021-07-29 20:50:52 字數 2314 閱讀 3803

傳送門

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...