bzoj2434: [noi2011]阿狸的打字機
阿狸喜歡收藏各種稀奇古怪的東西,最近他淘到一台老式的打字機。打字機上只有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 3sample output
2 1
0hint
1<=n<=10^5
1<=m<=10^5
輸入總長<=10^5
分析:網上的題解在我這個zz看來真是晦澀難懂啊,所以只能一點點研究,寫了一篇蒟蒻看的題解(大神勿噴):
這道題需要用到fail樹(實際上是所有fail指標反向構成的樹),簡單解釋一下:
在fail樹中,假使有乙個節點對應的字串為aa,那麼所有以aa為字尾字串都在這個節點的子樹裡。如果串x出現在串y中,那麼串y有幾個字首的字尾以串x結尾,便是出現的次數。而這些y串上的節點都會出現在x的子樹中。
簡單地說串y從某個位置順著fail指標能到達串x尾就增加一次。
我們需要計算的就是以x串最後乙個字元所在的節點為根的子樹中找到包含多少個y串中的節點,把x串最後乙個字元所在節點為根的子樹中的y串上的節點獨立出來,把這些節點的值賦為1,對於所有詢問我們先按照y排一遍序,以後就可以把每乙個y標記完的樹,處理所有對應的(x[i],y)詢問,求乙個區間和(樹狀陣列維護)
這裡寫**片
#include
#include
#include
#include
#include
using
namespace
std;
const
int n=100010;
int n,m,x,y;
char s[n];
int ch[n][26],fa[n],tot=0; //tot:節點數
int word[n]; //word:每個輸出字串對應結尾
int tt=0,fail[n],in[n],out[n],ed=-1; //ed:輔助dfs計數 tt:輔助記錄輸出字串的編號
struct node;
node tree[n*4]; //fail樹
int st[n],totw=0,ans[n]; //ans:記錄答案
struct node2;
node2 qes[n]; //記錄詢問
int c[n]; //樹狀陣列
int comp(const node2 & a,const node2 & b)
void build() //trie樹的構建
if (s[i]=='b')
if (!ch[now][x]) ch[now][x]=++tot,fa[ch[now][x]]=now;
now=ch[now][x];
}return;
}void make() //生成失配指標。順便反向建樹。
fail[ch[r][i]]=ch[fail[r]][i];
q.push(ch[r][i]);}}
for (i=1;i<=tot;i++)
add(fail[i],i);
return;
}void dfs(int t) //對fail樹dfs 根節點是0所以ed初始值是-1,保證t和ed的值能對應的上
out[t]=ed; //在dfs中的終止位置
}//樹狀陣列時建立在dfs序上的,這樣能確保同一顆子樹上的節點在序列中是連續的一段
void change(int bh,int z)
int ask(int bh)
void solve() //把字串重新遍歷一遍
else
if (s[i]=='b')
else}}
return;
}int main()
sort(qes+1,qes+1+m,comp);
solve();
for (int i=1;i<=m;i++)
printf("%d\n",ans[i]);
return
0;}
bzoj 2434 阿狸的打字機 fail樹的性質
如果a串是另b串的字尾,那麼在trie圖上沿著b的fail指標走一定可以走到a串。而a串在b串裡出現多少次就是它是多少個字首的字尾。所以把fail邊反向建樹維護個dfs序就行了。並不是很難。但沒想出來tat 1 include2 include3 include4 include5 define n...
NOI2011阿狸的打字機
阿狸喜歡收藏各種稀奇古怪的東西,最近他淘到一台老式的打字機。打字機上只有28個按鍵,分別印有26個小寫英文本母和 b p 兩個字母。經阿狸研究發現,這個打字機是這樣工作的 l 輸入小寫字母,打字機的乙個凹槽中會加入這個字母 這個字母加在凹槽的最後 l 按一下印有 b 的按鍵,打字機凹槽中最後乙個字母...
NOI2011 阿狸的打字機
阿狸喜歡收藏各種稀奇古怪的東西,最近他淘到一台老式的打字機。打字機上只有28個按鍵,分別印有 26個小寫英文本母和 b p 兩個字母。經阿狸研究發現,這個打字機是這樣工作的 輸入小寫字母,打字機的乙個凹槽中會加入這個字母 按 p 前凹槽中至少有乙個字母 按一下印有 b 的按鍵,打字機凹槽中最後乙個字...