題目描述 description
給你兩個串a,b,可以得到從a的任意位開始的子串和b匹配的長度。
給定k個詢問,對於每個詢問給定乙個x,求出匹配長度恰為x的位置有多少個。
n,m,k<=200000
輸入描述 input description
第一行三個數 n,m,k,表示a的長度、b的長度和詢問數。
第二行為串a。
第三行為串b。
接下來k行,每行1個數x。
輸出描述 output description
對於每個詢問輸出乙個數。
樣例輸入 sample input
6 2 2
aabcdeab0
2 樣例輸出 sample output 4
1 資料範圍及提示 data size & hint
各個測試點1s
假如有匹配串a長度為n,模式串b長度為m,那麼擴充套件kmp演算法可以在o(n+m)的時間內算出對於a的每乙個位置,與b的最長匹配長度是多少(即與b串字首重合的最長長度),演算法如下:
設next[i]表示b串的i位置開始的字串與b串的字首的最長重合長度(注意這裡與kmp中的next是不一樣的)。明顯地,next[1]=m(我的字串的下標習慣從1開始),next[2]也可以用乙個簡單的for迴圈求出,pos初始化為2;當i∈[3,m]時,我首先認為關於1~i-1的資訊已全部求出,我們記錄乙個pos,它的意義是當前已計算出的next陣列中,j+next[j]-1能達到的最右端所對應的i,這個不太好理解,可以參考manacher演算法的思想戳這(其實manacher和擴充套件kmp是很像的),令rp=pos+next[pos]-1
(1)當i+next[i-pos+1]
(2)當i+next[i-pos+1]>=rp時,rp後的元素,即b[rp+j],可能會和b[rp-i+1+j]相等,這時進行暴力擴充套件,如果擴充套件發生,則更新pos為i,next[i]直接在擴充套件中求出。
注意:有時rp可能小於i,這時可以加一特判,直接進行暴力求
令ans[i]表示a串中以a[i]為開頭的字尾和b串的最長匹配長度,設pos表示a串中對於所有的i,i+ans[i]-1能達到的最遠位置對應的i,rp就是pos+ans[pos]-1,next[1]暴力求出,pos初始化為1;當i∈[2,n]時:
(1)若i+next[i-pos+1]-1
(2)若i+next[i-pos+1]-1>=rp,則進行暴力擴充套件,同時更新pos,ans在擴充套件時求出
注意:如果rp
//codevs1404 字串匹配 擴充套件kmp
#include #include #include #define maxlen 200010
using namespace std;
char a[maxlen], b[maxlen];
int next[maxlen], n, m, k, cnt[maxlen], ans[maxlen], tong[maxlen];
void init()
else
if(i+next[i]-1>p)a=i;
} else next[i]=next[i-a+1]; }}
void exkmp()
else
}else ans[i]=next[i-pos+1];
if(i+ans[i]-1>rp)pos=i;
tong[ans[i]]++; }}
int main()
return 0;
}
CODEVS T 1404 字串匹配
時間限制 1 s 空間限制 128000 kb 題目等級 大師 master 題解檢視執行結果 給你兩個串a,b,可以得到從a的任意位開始的子串和b匹配的長度。給定k個詢問,對於每個詢問給定乙個x,求出匹配長度恰為x的位置有多少個。n,m,k 200000 輸入描述 input descriptio...
201409 3 字串匹配
試題編號 201409 3 試題名稱 字串匹配 時間限制 1.0s 記憶體限制 256.0mb 問題描述 問題描述 給出乙個字串和多行文字,在這些文字中找到字串出現的那些行。你的程式還需支援大小寫敏感選項 當選項開啟時,表示同乙個字母的大寫和小寫看作不同的字元 當選項關閉時,表示同乙個字母的大寫和小...
20140903 字串匹配
問題描述 試題編號 201409 3 試題名稱 字串匹配 時間限制 1.0s 記憶體限制 256.0mb 問題描述 問題描述 給出乙個字串和多行文字,在這些文字中找到字串出現的那些行。你的程式還需支援大小寫敏感選項 當選項開啟時,表示同乙個字母的大寫和小寫看作不同的字元 當選項關閉時,表示同乙個字母...