CQOI2014 萬用字元匹配

2021-10-02 10:43:51 字數 1543 閱讀 1603

點此看題

弱化版:[ahoi2005]病毒檢測

先把*當成分割符,這樣帶萬用字元的串就被劃分成了若干個小串,我們對於每乙個小串在去另乙個串中匹配。

對於每乙個小串,以?為分割符,將它插入ac

\text

ac自動機中,標記終止節點,把在小串中的終止位置存在ed[

x]

ed[x]

ed[x

]中(型別為vec

to

rvector

vector

),然後我們把乙個點在fai

lfail

fail

樹上到根的路徑的eded

ed全部合併到這個點上(方便查詢)。匹配另乙個串時,對於匹配到的位置i

ii,在自動機上訪問到了節點x

xx,我們把cnt

[i−e

d[x]

[j]+

1]++

cnt[i-ed[x][j]+1]++

cnt[i−

ed[x

][j]

+1]+

+,相當於標記可能的起始位置,匹配完後掃一遍cnt

cntcn

t,如果某個位置被標記的次數等於插入自動機的段數,那麼這個位置就可以作為大的匹配起始點。

本演算法的時間複雜度依賴於萬用字元個數。注意要考慮開始和結束的位置有沒有*,需要特殊判斷,具體實現可以看**:

#include

#include

#include

#include

using

namespace std;

const

int m =

100005

;int

read()

int t,n,m,beg,end;

char s[m]

,t[m]

;struct automaton

void

ins(

int l,

int r,

int id)

ed[now]

.push_back

(id);}

void

build()

}int

find

(int l,

int r,

bool f,

bool e)

build()

;for

(int i=

1,now=

0;i<=n;i++

)for

(int i=

1;i<=n;i++)if

(cnt[i]

==seg)

return0;

}}ac;

intmain()

i=pos;pd=0;

}if(!flag)

puts

("yes");

else

puts

("no");

}}

bzoj3507 Cqoi2014 萬用字元匹配

我們將題目輸入的那個含萬用字元的串,記為 萬用字元串 下面的檔名記為 檔名 檔名 數量很少可以依次查詢。我們先將 萬用字元串 以 為界,將 萬用字元串 分解,得到若干子串,記為 通配子串 我們將每個 通配子串 各建立乙個 ac自動機。而有的 通配子串 可能含 萬用字元,我們將再次按 為界,分解這個 ...

BZOJ3507 Cqoi2014 萬用字元匹配

必須要記住字串很好卡一不小心就o n 別問我為什麼這麼說.qaq 這題首先滿足位數與字母兩個限制,那麼我們 分大塊?分小塊,求各塊hash值,同時預處理出來每個字串的字首hash這樣就可以o 1 對比了 千萬不要忘記hash字串對比的功能,我在考試的時候一腦抽就忘了.include include ...

bzoj3570 Cqoi2014 萬用字元匹配

題目鏈結 給出乙個主串,裡面有些萬用字元,可以代替任意字串或者消失,可以且僅可以代替乙個字元。問能否用這個串匹配一些詢問串。也許我zz了,半天寫不出 f i j 表示主串到第 i 個匹配符,詢問串到第 j 個字元能否被匹配。轉移很簡單,hash一下就好了。在主串末尾新增乙個 bzoj3507 inc...