hash前面已經講過了,我們再用kmp做一下,對於kmp我們先要了解ne陣列:next[i]=j 以i為終點的字尾和從1開始的非平凡字首最大重合是j
我們先對b預處理出ne,然後對a進行匹配
for
(int i =
1, j =
0; i <= n; i++
)
我們知道,對於 j 表示的是b能匹配a以i結尾的最長長度是j ,也就是說,在a中子串a[i-j+1,i] 與 b[1,j] 相同(字串 a 中,以 i−j+1 為起點的與 b 匹配的長度最小為 j),那麼我們就用乙個陣列cnt[x]來記錄滿足匹配字首至少為x的字尾的數量
我們繼續看,對於cnt[j],能匹配,那麼cnt[cnt[j]]也一定能和原字串匹配,那麼我們就可以拓撲序累加,計算出所有的cnt陣列
最後 cnt[i] 存的是滿足匹配的字首至少為 x 的字尾數量,而題目中所要求的滿足匹配的字首恰好為 x 的答案的應為匹配的字首至少為 x 的字尾數量 減去 匹配的字首至少為 x + 1 的字尾數量,即 cnt[x] - cnt[x + 1](字尾和思想)
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
const
int n =
2e5+10;
int n, m, q, x;
char a[n]
, b[n]
;int ne[n]
, cnt[n]
;int
main()
for(
int i =
1, j =
0; i <= n; i++
)//更新cnt
for(
int i = m; i >
0; i--
) cnt[ne[i]]+
= cnt[i]
;while
(q--
)return0;
}
演算法競賽高階指南 0x00
快速冪模板,寫一下快速冪的原理。我們知道,乙個數 n 在二進位制 也可以是其他進製 下可以被表示為 a 1 a 2 2 1 a 3 2 2 a m 2 那麼我們可以考慮將其分拆成二進位制狀態下的每一位,然後做冪運算。這樣做的時間複雜度為 o log 2 n 實現的過程類似於倒過來的分治 當然也可以直...
《演算法競賽高階指南》0x32約數
求解 1,n 之間的最大的反素數,有性質 這個反素數是質因數個數最多的數中最小的乙個。證明 假設有乙個數質因數個數比它多,如果在他前面,不滿足反素數的定義,如果在他後面,一定可以找到第乙個質因數比它大的數,這個數作為結果更好,反證可知,這個數質因數一定是最多的 反證 假設有質因數與他的個數一樣但是比...
演算法競賽高階指南 0x18(棧)表示式計算4
括號序列,表示式的計算幾乎都是離不開棧的,對於表示式的計算,我們可以用兩個棧來分別儲存數字和字元,然後求解 規則 每次遍歷到運算子時,比較當前運算子和棧頂運算子的優先順序,只要是棧頂優先順序大於等於當前優先順序,那麼就可以將前面的式子計算 具體細節看 include include include ...