KMP板子 Trie板子

2022-05-10 04:13:54 字數 1933 閱讀 8222

kmp演算法是乙個字串匹配演算法,最直白的用法就是在乙個長度為n的字串t中查詢另乙個長度為m字串p的匹配(總之就是用於文字中進行單個字串的匹配)。

對於這個問題,暴力演算法是很好做的,直接對於t的每個位置判斷一下當前位置作為p的結尾是否可以匹配成功,演算法複雜度是o(nm)。

kmp演算法的主要思想是:假設現在正在用p的第j個字元和t的第i個字元進行匹配,如果成功就匹配下乙個字元;如果失敗的話就跳到 以j-1個字元為結尾的字尾的 最長相同字首的結尾 後乙個位置進行匹配。為此要把p做成乙個狀態機(也就是失配函式),在上面根據情況進行轉移。

複雜分析:每一次i增加的時候伴隨著j的增加,i增加的時候為j提供了減少的空間,因此j最多會減少n次。加上預處理的時間,總時間複雜度o(n+m)。(這次一定要好好記住,之前看一次忘一次。。。)

下面給出上面問題的**(n<=1000000,m<=10000)。

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include

9 #include10 #include11 #include12

using

namespace

std;

13const

int maxn=1000005;14

const

int maxm=10005;15

16int

n,f[maxn];

17char

p[maxm],t[maxn];

1819

void getfail(char *p)

2028}29

int find(char *t,char *p)

3038

return

re;39}40

intmain()

4147

return0;

48 }

trie是一種可以讓你歡快的在字典中查詢單詞的資料結構,所以單次查詢時間複雜度為什麼是o(1)。。。。。。

下面的**是這樣乙個問題:給出乙個長字串和一些字典中的單詞,問用這些單詞拼接出長字串的方案數mod20071027答案是多少,單詞可以重複使用。倒著插入所有字典之後dp就可以了。

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include

9 #include10 #include11 #include12

using

namespace

std;

13const

int maxn=1000005;14

const

int maxm=105;15

const

int mo=20071027;16

17int

n,f[maxn];

18char

t[maxn],s[maxm];

19struct

trie

24void insert(char *s)

2533 now=ch[now][s[i--]-'a'

];34

}35 val[now]++;36}

37int find(int

i)38

45if(!i&&val[ch[now][t[i]-'

a']]) re=(re+1)%mo;

46return

re;47}48

}trie;

4950

void

data_in()

5157}58

void

work()

5964

intmain()

65

KMP 初級板子 待更新

複雜度 o n m 這個博主寫的蠻不錯的 1.本文中,所有的字串從0開始編號 2.為了在程式中表示方便,在接下來的說明中,next i 0表示最長相同字首字尾長度為 即真實的最長相同字首字尾 next i 1。重要的內容要放大 includeusing namespace std const int...

KMP 初級板子 待更新

複雜度 o n m 這個博主寫的蠻不錯的 1.本文中,所有的字串從0開始編號 2.為了在程式中表示方便,在接下來的說明中,next i 0表示最長相同字首字尾長度為 即真實的最長相同字首字尾 next i 1。重要的內容要放大 includeusing namespace std const int...

板子 KM(n3板子)

include using namespace std define ll long long 演算法使用 w maxn maxn 陣列表示圖的鄰接矩陣 pop表示二分圖的左右兩邊的點的數量 點從0到n 1 const int maxn 50 const int inf 0x3f3f3f3f int...