a637: Rabin-Karp v.s. Birthday Paradox
標籤 :
通過比率 : 1人/2人 ( 50% ) [非即時]
評分方式:
Tolerant

最近更新 : 2022-09-22 03:21

內容

本題為教學題所以很裸很水。

你有聽過 Rabin-Karp fingerprint algorithm 嗎?這是一種 string hash 演算法,常用於做字串匹配,由於它可以在 $O(n)$ 時間預處理並在 $O(1)$ 時間查詢任一子字串的 hash 值,往往可以做到確定性演算法中要用複雜的 suffix array 之類的演算法才能做到的事情。

然而,既然是 hash 就會有碰撞問題,估計碰撞機率並在一開始就判斷好要怎麼實作是很重要的。假設 rabin-karp 的模數為 $M$ ,已知兩個字串碰撞的機率約為 $\frac{1}{M}$ ,做 $N$ 次兩字串相等判斷的碰撞機率則為 $\frac{N}{M}$,而特別的是如果是一個大小 $N$ 的字串集合,那麼根據生日問題,如果 $M=\Omega(N^2)$ 就會有高機率產生碰撞。換句話說一個大小約為 $30000$ 的集合在常見 int 範圍內的模數就有很高的機率會產生碰撞了。

為了避免這樣的問題,因此存在好幾種提升模空間 $M$ 的大小的方法。第一種最直觀的想法就是令模數 $M$ 是 long long 等級的數字,然而問題是運算會到 int128 數量級導致運算速度極慢通常會得到 TLE。第二種常見的作法則是 multiple (double) hash,也就是用兩組以上的 int 範圍 hash 參數來組成 hash tuple 來讓模空間 $M=m_1m_2$ 大約是 long long 的數量級,然而 hash 中所使用的模運算效率很差,做 multiple hash 也會直接讓運算量倍增影響效率有時沒寫好也會得到 TLE。

那麼是否存在方法可以有 long long 等級的模空間又有高運算效率呢?答案是有的。既然第一種方法的瓶頸是在運算量級會溢位,且兩種方法都存在模運算很慢的問題,那麼使用自然溢位就兩個問題都能解決了。使用自然溢位的話直接省掉了模運算,又不用考慮溢位問題可以安心的做任意運算,如果型態設為 (unsigned) long long 的話就可以有 long long 數量級又效率很高的 hash 方法了,而且實作上甚至不用考慮模運算的問題寫起來更為簡單。心動不如馬上行動,本題將是裸的大字串集的匹配計數問題。

輸入說明

第一行輸入兩個數字 $N,t$ 代表接下來有 $N$ 個字串以及長度下限 $1\le t\le 2\times 10^5$。

第 $2\sim N+1$ 行每行各有一個非空字串 $S_i$,其中字串只包含小寫英文字母。

$\sum\limits_{i=1}^N {|S_i|-t+2\choose 2}\le 5\times 10^6$ 其中 $n\choose m$ 代表組合數,也就是 $C^n_m$ 的意思。換句話說也就是總子字串數量不超過 $5\times 10^6$

$\sum\limits_{i=1}^N |S_i|\le 5\times 10^6$

輸出說明

假設可重集合 $S=\{S_i[j\dots k]|1\le i\le N, 1\le j\le k\le |S_i|, k-j+1\ge t\}$ 也就是所有字串的所有長度至少 $t$ 的子字串所組成的可重集合,並令 $S'$ 為 $S$ 的去重集合

那麼請輸出一個整數代表 $\sum\limits_{s\in S'}{\text{multiplicity of s in S}\choose 2}$ 。換句話說也就是輸出對於每個相異字串,其出現次數取2的總和。也等價於所有相同字串出現在相異位置的配對數量總和。

範例輸入
3 1
abc
aba
ba
範例輸出
11
測資資訊:
記憶體限制: 512 MB
不公開 測資點#0 (2%): 1.0s , <1K
不公開 測資點#1 (2%): 1.0s , <1K
不公開 測資點#2 (2%): 1.0s , <1K
不公開 測資點#3 (2%): 1.0s , <1K
不公開 測資點#4 (2%): 1.0s , <1K
不公開 測資點#5 (2%): 1.0s , <1K
不公開 測資點#6 (2%): 1.0s , <1K
不公開 測資點#7 (2%): 1.0s , <1K
不公開 測資點#8 (2%): 1.0s , <1K
不公開 測資點#9 (2%): 1.0s , <1K
不公開 測資點#10 (2%): 1.0s , <1K
不公開 測資點#11 (2%): 1.0s , <1M
不公開 測資點#12 (2%): 1.0s , <1M
不公開 測資點#13 (2%): 4.0s , <1M
不公開 測資點#14 (2%): 4.0s , <1M
不公開 測資點#15 (2%): 1.0s , <1M
不公開 測資點#16 (2%): 1.0s , <10M
不公開 測資點#17 (2%): 1.0s , <10M
不公開 測資點#18 (2%): 1.0s , <10M
不公開 測資點#19 (2%): 1.0s , <1M
不公開 測資點#20 (3%): 4.0s , <1M
不公開 測資點#21 (3%): 3.0s , <1M
不公開 測資點#22 (3%): 1.0s , <1M
不公開 測資點#23 (3%): 4.0s , <1M
不公開 測資點#24 (3%): 4.0s , <1M
不公開 測資點#25 (3%): 3.0s , <1M
不公開 測資點#26 (3%): 4.0s , <1M
不公開 測資點#27 (3%): 4.0s , <1M
不公開 測資點#28 (3%): 3.0s , <1M
不公開 測資點#29 (3%): 4.0s , <10M
不公開 測資點#30 (3%): 4.0s , <1M
不公開 測資點#31 (3%): 4.0s , <10M
不公開 測資點#32 (3%): 4.0s , <1M
不公開 測資點#33 (3%): 4.0s , <10M
不公開 測資點#34 (3%): 4.0s , <1M
不公開 測資點#35 (3%): 4.0s , <1M
不公開 測資點#36 (3%): 4.0s , <1M
不公開 測資點#37 (3%): 4.0s , <10M
不公開 測資點#38 (3%): 4.0s , <1M
不公開 測資點#39 (3%): 4.0s , <10M
提示 :

你從本題學到了什麼呢XD

建議可以各種方法都試試看來比較各種方法的差異、優劣等XD

標籤:
出處:
[管理者:
giver (垃圾)
]


編號 身分 題目 主題 人氣 發表日期
沒有發現任何「解題報告」