NOI2011 JZOJ2784 阿狸的打字機

2021-07-09 16:43:25 字數 2485 閱讀 1088

有乙個快取槽,設計乙個程式維護下面三個操作: ∙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 條雙向道路。每條道路的修建都要付出一定的費用,這個費用等於道路長度乘以道路兩端 的國家 個數之差的絕對值。例如,在下圖中,虛線所示道路...