傳送門
先想想暴力怎麼搞
搞乙個ac自動機
對每個詢問 x,y
把 y 暴力向下匹配
每個點都暴力跳fail
看看x出現了幾次
稍微優化一波
因為有多組詢問
考慮離線
可以把同一組的 y 一起來計算
還是把 y 暴力匹配
看看所有的x 出現了幾次
再來一波優化
考慮什麼時候 x 的出現次數會增加
顯然是在 y 的某個節點的 fail 路徑上
因為每個點只有乙個 fail
所以所有的 fail 構成了一顆樹
如果把 fail 看成無向邊,根節點為自動機的根節點
那就相當於問在fail樹的x的結束節點的子樹中,有幾個節點屬於y
那麼詢問 x,y 就只要在ac自動機上跑到y
路過的每乙個節點就把 記錄值+1
然後詢問 在fail樹中 x 的結束節點的子樹 記錄值之和為多少
對於這種對子樹的詢問
用什麼方法最好呢?
樹鏈剖分!
為什麼這麼麻煩
雖然不可能用樹剖
但是可以用樹剖的思想
給每個節點乙個dfs序
在ac自動機上跑的時候
每經過乙個節點就把該節點的dfs序的值+1
退出該節點時就-1
然後詢問就像樹剖的子樹詢問一樣了
因為每次是單點修改,區間求和
所以用樹狀陣列維護一波就好了
總結一下
把每個操作離線
把y相同的詢問放在一起
dfs一波,每次找到結束標記
就把相關的詢問處理
具體的實現在**裡
#include#include#include
#include
#include
#include
using
namespace
std;
inline
intread()
returnx;}
const
int n=1e5+7
;char
s[n];
intfa[n];
intn,m;
int c[n][27],pd[n],fail[n],cnt,las[n];//
las[i]表示第i個串的結束節點的位置
inline void build()//
處理操作並構造出ac自動機
}}//
以下為預處理fail並構造出fail樹
queue q;
int fir[n],from[n],to[n],cnt2;//
存fail樹
inline void add(int a,int
b)//
向fail樹中加邊
int c[n][27];//
存原ac自動機的結構,因為處理fail時會把ac自動機的結構改變
//等等還要用原來的結構來dfs處理詢問
void
pre()
}}//
以上為預處理fail並構造出fail樹
//第一波dfs確定dfs序
int dfn[n],sz[n],cnt3;//
dfn是dfs序,sz是子樹大小
void dfs1(int
x)//
以下為樹狀陣列
intt[n];
inline
void add(int x,int v)
inline
int query(int
x)//
以上為樹狀陣列
//以下存詢問
struct
data
d[n];
inline
bool cmp(const data &a,const data &b)
int l[n],r[n];//
l[i]表示排序後y值為i的區間的左端點,r為右端點
//以上存詢問
void dfs2(int
x) add(dfn[x],-1);//
退出時值要改回來
}int
ans[n];
intmain()
r[d[m].y]=m;
dfs1(
0);//
確定dfs序
dfs2(0);//
dfs處理詢問
for(int i=1;i<=m;i++)
ans[d[i].id]=d[i].ans;//
按原來的順序把答案放到答案陣列裡
for(int i=1;i<=m;i++) printf("
%d\n
",ans[i]);
return0;
}
P2414 NOI2011 阿狸的打字機
打字機上只有28個按鍵,分別印有26個小寫英文本母和 b p 兩個字母。經阿狸研究發現,這個打字機是這樣工作的 輸入小寫字母,打字機的乙個凹槽中會加入這個字母 這個字母加在凹槽的最後 按一下印有 b 的按鍵,打字機凹槽中最後乙個字母會消失。按一下印有 p 的按鍵,打字機會在紙上列印出凹槽中現有的所有...
P2414 NOI2011 阿狸的打字機
p2414 noi2011 阿狸的打字機 顯然跟處理字串有關,但具體用什麼呢?一次列印有可能會列印之前重複過的,當然是 trie 之後查詢作為子串出現過幾次,看看前面的 trie 當然用 trie 圖了 先考慮暴力,y 所在串的每個字元跳 fail 是否能到 x 的末尾 在 parents 樹尤拉序...
NOI2011 JZOJ2784 阿狸的打字機
有乙個快取槽,設計乙個程式維護下面三個操作 i nser tc 在快取槽末尾插入小寫字元c pri nt 將快取所有字元連線輸出為字串 d elet e 刪除快取槽最後乙個字元 操作總共有 n 個。在所有操作結束之後,要支援 m個詢問。每個詢問都是查詢第 x 次輸出的字串在第 y次輸出的字串中出現了...