首先不難想到字串hash的做法,列舉a中的每個位置,二分匹配長度即可,時間複雜度\(o(n)\)。
很明顯正解應該要用kmp,但對於匹配出的乙個f[i]我們只能知道「有一次長度至少為f[i]的匹配」,同時還可能會漏掉一些匹配位,怎麼辦?
基於值域的字首和
即令cnt[x]=長度至少為x的匹配位的個數,易得答案等於cnt[x]-cnt[x+1]。
因此,我們可以先把由f陣列可直接得出的匹配位統計進cnt陣列。
對於哪些被遺忘的匹配位,由kmp的基本引理2可得分別是f[i]=nxt[i],nxt[nxt[i]],...。倒序迴圈累加一下即可。
字串hash:
#include#includeusing namespace std;
typedef unsigned long long ull;
const int maxn=200005;
const ull p=13141;
char a[maxn],b[maxn];
ull pm[maxn],ha[maxn],hb[maxn];
int n,m,q,cnt[maxn];
inline int match(int p)
return res;
}int main()
return 0;
}
kmp:
#include#includeusing namespace std;
const int maxn=200005;
char a[maxn],b[maxn];
int n,m,q,cnt[maxn],nxt[maxn],f[maxn];
int main()
for(int i=1,j=0;i<=n;i++)
for(int i=1;i<=n;i++) cnt[f[i]]++;
for(int i=m;i>=1;i--) cnt[nxt[i]]+=cnt[i];
while(q-->0)
return 0;
}
題解 CH1809 匹配統計
首先不難想到字串hash的做法,列舉a中的每個位置,二分匹配長度即可,時間複雜度 o n 很明顯正解應該要用kmp,但對於匹配出的乙個f i 我們只能知道 有一次長度至少為f i 的匹配 同時還可能會漏掉一些匹配位,怎麼辦?基於值域的字首和 即令cnt x 長度至少為x的匹配位的個數,易得答案等於c...
CH1809 匹配統計 題解
看了好久才懂,我好菜啊 題意 給兩個字串 a 與 b 對於 q 次詢問,每次詢問給出乙個 x 求存在多少個位置使得 a 從該位置開始的字尾子串與 b 匹配的長度恰好為 x 這題可以 hash 二分 o n log n 過,還有乙個高階做法是擴充套件 kmp 然而並不會 正解的話,還是 kmp。但此題...
CH1809 匹配統計 KMP
求恰好匹配 x xx 長度比較困難,可以轉為求至少匹配 x xx 長度的位置,再作差。用kmp演算法可以求出每個位置最多匹配的長度,而這個長度其實是 於 nex t i nex t ne xt i next i next next i next i ne xt n ext i 因此對於他們,求至少匹...