CEOI2011 mat solution中文翻譯

2021-06-01 08:50:32 字數 3208 閱讀 9649

這個問題描述了乙個字串匹配的變種問題。給定兩個串,模式串p[1..n]和文字串t[1..m]。任務是找出所有的位置j,1 <= j <= m - n + 1,滿足模式串在位置j匹配文字串。而且,在這個問題中,模式串和文字串都是互異整數列。

而且,模式串p不是直接給出來的。給定乙個數列s來描述p:s1是p中最小的元素,s2是第二小的……任意乙個等於輸入的p都是等價的,所以我們假定p是1..n的乙個排列。這種表示很容易由s在o(n)計算出來。

在大部分模式串匹配問題中,模式串與母串在位置j匹配當且僅當p=t[j..j+n-1]。這個問題給出了一種不同的串匹配定義,模式串與母串匹配,當且僅當p與t[j..j+n-1]是同構的。我們稱呼兩個長度為k的串同構,當且僅當a[i] < a[j] <==> b[i] < b[j] forall i <= i, j <= k。

為簡化符號,我們把a與b同構寫成a~b。下面,我們有兩個簡單但是重要的結論。給定三個長為k的序列a,b,c。

1. 如果a ~ b,則a[x..y] ~ b[x..y] for i <= x <= y <= k

2. 如果a ~ b且b ~ c,則a ~ c。

為了解決這個問題,我們拓展了kmp演算法來滿足需求。接下來,我們假定讀者熟悉kmp演算法。

失敗指標:

我們定義:乙個序列a[1..k]的邊界為,a[1..k]的乙個長為t的字尾,且這個字尾與a[1..t]相似。在kmp演算法中,我們一開始要計算失敗指標f。對於每個1 <= i <= n,我們想知道串p[1..i]除自己本身外的最長邊界是什麼:

f[i] = max 0 <= k < i

另外,我們把f[0]設為0。

我們以i遞增的順序來計算f[i]。p[1..i]的最長邊界包括p[1..i - 1]的一部分和字母p[i]。我們遍歷p[1..i - 1]的所有邊界,從最長的開始,對於每個邊界,我們檢查新增乙個字母p[i]後能否構成p[1..i]的乙個邊界。

我們用下面的引理來遍歷所有邊界,它的證明稍後給出。

引理1:p[1..i]的所有邊界的長度依次為f[i], f[f[i]], f[f[f[i]]], f[f[f[f[i]]]]...

注意:由於0 <= f[i] < i,上述序列從某些點開始就只出現0了。

現在仍然遺留乙個問題:如何判斷p[1..i - 1]的乙個邊界加上乙個字母p[i]後可以構成p[1..i]的乙個邊界。換句話說,給定兩個串a[1..k]、b[1..k](前者是模式串的乙個字首,後者是模式串的乙個子串),已知a[1..k - 1] ~ b[1..k - 1],如何判斷a[1..k] ~ b[1..k]。注意到這就是判斷是否:

a[q] < a[k] <--> b[q] < b[k] for all 1 <= q < k

這可以按照下面這個方式重新表述(注意每個序列a、b的元素都是不同的):

性質1:對於一些1 <= r <= k,a[k]是a[1..k]中第r大的元素,b[k]是b[1..k]中第r大的元素。

我們現在描述乙個檢查是否滿足上述條件的方法。

設a[u]是a[1..k - 1]中比a[k]小的元素中最大的乙個,a[w]是a[1..k - 1]中比a[k]大的元素中最小的乙個。我們假定這些元素存在,其他情況類似。根據定義,a[u] < a[k] < a[w]。我們可以知道判斷b[u] < b[k] < b[w]是否成立是與判斷性質1等價的。這是因為a[1..k - 1] ~ b[1..k - 1],所以a[1..k - 1]中比a[u]小的數的個數等於b[1..k - 1]中比b[u]小的數的個數。類似的,a[1..k - 1]中比a[w]大的數的個數等於b[1..k - 1]中比b[w]大的

數的個數。所以,這個檢測與性質1實質上是等價的。

現在,我們討論如何計算u和w的下標。對於每個1 <= i <= n,我們需要在p[1..i]找到比p[i]小的最大元素,把這個下標記作g[i]。我們也需要知道比p[i]大的最小元素,記作h[i](這是乙個對稱的問題)。

注意到p[1..n]是乙個1..n的排列。我們維護乙個由p[1..i]的所有元素構成的遞增的雙向鍊錶。初始時他只是乙個1..n的所有元素構成的鍊錶。每一步都要刪除乙個元素。我們記錄鍊錶中的每個元素在p[1..n]中的位置,也記錄p[1..n]的每個元素在鍊錶中的位置。鍊錶允許我們對於每個i,可以在常數時間內獲得與p[i]最接近的元素——他們只是鍊錶中,刪除了n - i個元素之後,p[i]的前驅與後繼。

這就給出了乙個計算失敗指標的演算法。o(n)預處理出陣列g[i..n]與它的對稱問題h[i..n]之後,演算法就與kmp演算法的失敗指標的計算完全一致了。整個演算法的執行時間為o(n)。

尋找匹配

kmp匹配演算法的主要過程,大概講如下:

給定模式串的一部分,盡量拓展乙個字元。如果不可行,用失敗指標得到乙個稍短的部分匹配,繼續匹配文字。

這也是我們在這個問題中要做的事。用上面的方法,我們能夠在常數時間內判斷乙個部分匹配能不能再拓展乙個字元。正確性的證明很簡單,主要思想是:如果我們跳過一些正確的匹配(即,我們用失敗指標把部分匹配移動得太多超過了匹配的開始),我們馬上就得到這與失敗指標的定義是矛盾的。

最後,由於匹配過程只是kmp演算法的輕微修改,所以在o(n+m)的時間內可以出解。所以,整個演算法只需要線性時間。

引理1的證明:

我們證明,如果p[1..i]有乙個長度為t的邊界,那麼比t短的最長的邊界長度為f[t]。如果f[t] = 0,那麼長度為t的邊界是最短的乙個。從邊界的定義可以知道,p[1..t] ~ p[i - t + 1..i]。

我們首先證明p[1..i]有乙個長度為f[t]的邊界。首先,注意到p[1..t] ~ p[i - t + 1..i]。由此得出,對於每個1 <= s < t,p[1..t]有乙個長度為s的邊界。此外,任意乙個p[1..t]的邊界與p[i - t + 1..i]的邊界相似。所以,乙個長度為f[t]的p[1..t]的邊界與長為f[t]的p[i - t + 1..i]的邊界相似。這就表明p[1..f[t]] ~ p[i - f[t] + 1..i]。

為了完成這個證明,我們得證明沒有長度嚴格在f[t]與t之間的邊界存在。為了證明這個,我們證明每乙個這樣長度的邊界一定也是p[1..t]的邊界,否則會和f[t]的定義相矛盾。設f[t] < u < t且p[1..u] ~ p[i - u + 1..i],也就是說,p[1..i]有乙個長度為u

的邊界。這意味著p[1..t]的乙個長度為u的字尾與p[1..t + 1..t]的乙個長度為u的字尾相似。我們已經知道p[1..t]和p[i - t + 1..i]相似,所欲p[i - t + 1..i]的乙個長為u的字尾與p[1..i]的乙個長為u的字尾相似。所以p[1..t]的乙個長為u的字尾與p[1..u]相似,矛盾。

膜拜宇宙大農統neroysq!

我的2011 在迷惘中成長

我的2011,有過希望有過失望,有過衝動有過麻木 有歡笑也有淚水,有收穫也有付出 繼續走繼續迷失,2011,我在迷惘中成長。2011對我來說是很平淡的一年,乙個人走過,一路的艱辛,但總歸還是有收穫的,讓我懂得了很多,也讓我淡定了許多,感情上也沒有什麼好談的了。工作上對我來說還是挺有收穫的一年,起碼現...

XMLSpy 2011中文破解版

xmlspy 2011中文版破解補丁使用方法 3 使用序號產生器 keymaker.exe 提示與建議 2 安裝前最好斷網,或者遮蔽官網的驗證 有的同學問道會出現用了幾天就用不了的情況,這是因為連網時軟體會連線官方伺服器檢驗軟體是否為正版,遮蔽官網就行了,如下 127.0.0.0 altova.co...

MS CRM 2011中的實體 一) 概述

什麼是實體 ms crm借用了xml規範中的術語,以命名其系統中的包含的各項內容。這其中,最重要的,非實體莫屬了。實體,英文叫做entity,可以模擬於物件導向中的類,資料庫中的資料表。實體中包含有屬性attribute,可以模擬於物件導向中的屬性property,資料庫中的資料列。實體中包含有關係...