有乙個快取槽,設計乙個程式維護下面三個操作: ∙i
nser
tc:在快取槽末尾插入小寫字元c
∙pri
nt:將快取所有字元連線輸出為字串 ∙d
elet
e :刪除快取槽最後乙個字元
操作總共有
n 個。
在所有操作結束之後,要支援
m個詢問。每個詢問都是查詢第
x 次輸出的字串在第
y次輸出的字串中出現了多少次。1≤
n,m≤
100000
這道題需要靈活運用ac
自動機的性質。我搞了乙個下午,發現自己原先對ac
自動機的理解不夠透徹。做掉這題之後收穫比較多。
最暴力的方法肯定就是將所有詢問全部搞出來跑km
p ,但是這種方法太蠢了。顯然,我們將把有串建乙個ac
自動機會更好。由於操作的特殊性,我們能可以通過模擬指標在tr
ie上的進退來在o(
n)的時間複雜度完成建tr
ie操作(每次操作最多會改變一位字元)。
那麼我們建好ac
自動機之後怎麼去求答案呢?首先我們要清楚ac
自動機的一條性質:一條從ro
ot到x
的路徑上所有節點以及它們的fa
il祖先(就是一直fa
il上去),一定能表示出以
x 為結尾點的字串所有在自動機中出現過的子串。
那麼如果x在
y 中出現過,那麼
x的結尾肯定是這些點中的乙個或多個。所以我們可以考慮解決詢問時直接從將這些點暴力一遍。
但是這樣還是太蠢了,時間複雜的特別大。所以我們逆向思維,乙個以點
x 為結尾的字串的,從點
x開始沿著fa
il的反向往下走,遇到的所有點表示的字串一定包含原串。
所以我們建出fa
il樹(所有fa
il邊反向構成),那麼詢問就變為查詢
x 為根的子樹中在
y點到根路徑上的的點的個數。
怎麼解決這個詢問呢?我們對fa
il樹進行df
s ,求出df
s 序。那麼一棵子樹中所有點的序都是連續的,我們將點
x 掛在點
y上,像建tr
ie時一樣模擬指標在tr
ie上的移動,維護乙個陣列,第一次訪問乙個點時,將以該點df
s 序為下標的位置加
1 ,最後一次離開該點時減
1,這樣就可以表述出這條路徑上所有的點。當前操作為輸出操作時,我們直接找出所有掛在目前指標上的詢問,對子樹的連續區間求和即可統計答案。這個陣列用樹狀陣列或線段樹來維護就好了。
時間複雜度o(
(n+m
)log
n2) ,空間複雜度o(
n)。
具體細節見**實現。
∙ 建立ac
自動機的fa
il樹,然後資料結構維護是很多字串習題的常用方法,要注意學習。 ∙
ac自動機的性質要理解透。
#include
#include
#include
#include
using
namespace
std;
const
int n=100005;
const
int m=100005;
const
int s=100005;
const
int c=26;
int top[n],nxt[m],qu[m],w[n],ans[m];
int n,m,l,mt;
char str[s];
struct bit
void edit(int x,int y)
return ret;
}}bit;
struct tree
void dfs(int x)
}}t;struct ac_automation
void init()
void insert()
rt=next[rt][str[i]-'a'];}}
void build()
while (!q.empty())
q.pop();
}for (int i=1;ivoid solve()
else
if (str[i]=='p')
}else
bit.edit(t.dfn[0],-1);
}}ac;
void hang(int x,int y)
int main()
ac.solve();
for (int i=1;i<=m;i++)
printf("%d\n",ans[i]);
fclose(stdin);
fclose(stdout);
return
0;}
NOI 2011 道路修建
在 w 星球上有 n 個國家。為了各自國家的經濟發展,他們決定在各個國家 之間建設雙向道路使得國家之間連通。但是每個國家的國王都很吝嗇,他們只願 意修建恰好 n 1 條雙向道路。每條道路的修建都要付出一定的費用,這個費用等於道路長度乘以道路兩端 的國家個數之差的絕對值。例如,在下圖中,虛線所示道路兩...
NOI2011 道路修建
time limit 10 sec memory limit 128 mb submit 3967 solved 1367 submit status discuss 在 w 星球上有 n 個國家。為了各自國家的經濟發展,他們決定在各個國家 之間建設雙向道路使得國家之間連通。但是每個國家的國王都很吝...
NOI2011 道路修建
在 w 星球上有 n 個國家。為了各自國家的經濟發展,他們決定在各個國家 之間建設雙向道路使得國家之間連通。但是每個國家的國王都很吝嗇,他們只願 意修建恰好 n 1 條雙向道路。每條道路的修建都要付出一定的費用,這個費用等於道路長度乘以道路兩端 的國家 個數之差的絕對值。例如,在下圖中,虛線所示道路...