?
給定一個長度為 \(n\) 的字串序列 \(S\),字符集為小寫字母。\(m\) 次詢問,每次給定含恰好一個萬用字元的串 \(T\),詢問 \(T\) 能和多少 \(S_i\) 匹配。
\(\sum |S_i|+|T| \leq 3 \cdot 10^6\),\(n, m \leq 10^5\)。
對於每個串 \(s\) 和每個 \(i < |s|\),在 Trie 樹的 \(s_{1 \dots i}\) 處打一個標籤 \(s_{i+1\dots |s|}\),雜湊維護之。
複雜度線性。
gym103409H
把串分成很多個形如 \([r \cdot 2^k, (r + 1)\cdot 2^k)\) 的樣子。對詢問串建 AC 自動機,我們需要求出模式串經過 AC 自動機的每個點多少次。
\(f_{u, k, 0/1}\):從 ACAM 的點 \(u\) 出發,走 \(s_{0 \sim 2^k-1}\) 或 \(s'_{0 \sim 2^k-1}\) 步會到達哪個節點。有 \(f_{u, k, 0} = f_{f_{u, k-1, 0}, k-1, 1}\)。
考慮 \(c_{u, k, 0/1}\) 為使用 \(f_{u, k, 0/1}\) 轉移的次數,考慮用
更新 \(g_{u, k, 0/1}\),最後 \(g_{u, 0, 0} + g_{u, 0, 1}\) 即為經過的次數。
CF1801G
考慮 \(s_{1\dots r}\) 的匹配數減去 \(s_{1\dots l-1}\) 的匹配數,多餘的部分跨越 \(l\)。
分解 \((A, B)\),\(A\) 是 \(s_{1 \dots l-1}\) 的字尾,\(B\) 是 \(s_{l \dots n}\) 的字首,且 \(A+B \in \{s_i\}\)。
gym104090l
P4770
首先對每個 \(r\) 求一個最小的 \(l\) 使得 \(T[l, r] \in S\)。
尋找的方法是,增量,跳 fail 跳到有 \(T_r\) 的出邊,走過去。(直接跳好像就是對的)
這樣可以對一個 \(s\) 做,利用 SAM 遍歷 \(T\) 的所有子串並透過 \(l\) 就行了。
接下來要擴充到 \(s[l, r]\) 的情況。
還是考慮維護所有 \(l\)。我們掃右端點並同時維護每個子串最靠右的出現,考慮動態更新每個點子樹內 endpos 值最大且不超過 \(r\) 的數值 \(c_i\),則每次要把一個點 fail 樹上到根的所有祖先一起賦值。設當前串的長度為 \(m\),列舉到的右端點為 \(r_0\),當前在詢問 \(s[l, r]\),找到 \(s[l+m-1, r]\) 區間的 endpos 集合是否有 \(r_0\)。至於 \(T[1, r_0]\) 有幾個字首出現過,利用 \(c\) 求當前區間與 \(T[1, r_0]\) 的最長公共字尾就行了。
P6292
gym104901L
分段 dp:\(f_{i, j, 0/1}\) 表示前 \(i\) 段選 \(j\) 段且最後一段是否被選,有
考慮到第一種轉移中 \(i-j\) 不變,以 \(i-j\) 為第一維做 dp,同時試圖用資料結構維護最優的選擇點。
考慮 \(w(i', i)\) 的變化,當 \(i\) 為某個集合的 \(r\) 時,所有 \(i'<l\) 的 \(w(i', i)\) 都會增加,也就是字首加。
需要維護的是,後面插數,字首加,全域性最大值,線段樹維護之,複雜度 \(O(n^2 \log n + nm)\)。