[CF1168D] Anagram Paths
link
設 \(f_{u, i}\) 表示 \(u\) 子樹中字元 \(i\) 至少需要出現的次數,那麼 \(f_{u, i} = \max\limits_{v \in son(u)} f_{v, i}\)。整棵樹合法當且僅當所有葉子深度相同,且對於所有點 \(u\) 滿足 \(\sum\limits_i f_{u, i}\le d_u\),其中 \(d_u\) 為 \(u\) 子樹深度。發現二叉樹的條件比較特殊,如果把所有二度點縮點,發現每個葉子的深度都是 \(\mathcal O(\sqrt n)\) 的。直接暴力跳父親即可。
- 啟示:時間複雜度分析。
[SNOI2020] 字串
link
暴力做,可以把兩個字串的所有長度為 \(k\) 的子串全部扔進 trie 裡面,然後貪心匹配。
可以看出需要建立 SAM。由於是固定相同字首,存在不同字尾,所以考慮建立兩個串反串的廣義 SAM,然後和 trie 就沒什麼區別了。
- 啟示:觀察資料結構的特點,進一步擴充套件。
[Ynoi2001] 冷たい部屋、一人
link
考慮每種數按出現次數根號分治。
對於出現次數 \(\le B\) 的數,發現總對數 \(\le \mathcal O(nB)\)。考慮暴力列舉,用 ST 表求出每一對相同的數之間的 min 和 max,將 max 掃描線。注意到空間是帶根號的,考慮對於每一個 max 值求出其管轄的範圍,記錄並掃描線。
對於出現次數 \(> B\) 的數,種數 \(\le B\),考慮對每一種數都做一遍莫隊。具體的,將詢問離散化(需要線性),然後把每兩個相鄰相同數字之間的 \([\min, \max]\) 掛到對應 \(\min\) 和 \(\max\) 位置上,不難發現每個位置至多掛兩個區間。然後做回滾莫隊,連結串列維護。
- 啟示:根號分治大法好。
[Ynoi2011] WBLT
link
這種題一定是需要 bitset 的,考慮用莫隊處理出每個詢問區間出現的數的 bitset。然後將該 bitset 分裂為若干個長度為 \(b\) 的小 bitset,依次按位與起來。
當 \(b\) 過小時複雜度會出錯,考慮類根號分治,當 \(b\le 64\) 時,每種數做一次 bitset。
- 啟示:bitset 與莫隊結合;類根號分治。
[Ynoi2002] Optimal Ordered Problem Solver
link
[CF1876G] Clubstep
link
考慮一個詢問,依次 \(i = r\dots l\),若 \(x > a_i\),則造成 \(\lceil \frac {x - a_i} 2\rceil\) 貢獻,然後 \(x\gets \lfloor \frac {x + a_i} 2 \rfloor\)。
考慮離線掃描線,每次加入若干個 \(x\),或者刪掉若干 \(x\),我們需要維護一個 \(x\) 的集合,每經過一個 \(a_i\) 都要更新一遍。這個很難維護,接下來是魔法。設當前集合中 \(x\) 從小到大為 \(x_{1\dots k}\),考慮勢能 \(f = \sum\limits_{i = 2} ^ k \log_2 (x_i - x_{i - 1})\),發現每更新一個 \(x\),\(f\) 至少減小 \(1\)。\(f\) 增加值總和為 \(\mathcal O(q\log V)\),所以可以暴力更新那些 \(> a_i\) 的 \(x\)。對於相同的 \(x\) 勢能分析失效,需要用並查集將其合併,並查集需要帶權。時間複雜度 \(\mathcal O(n + q\log ^2 V)\)。
- 啟示:勢能,時間複雜度分析。
[Ynoi2007] rgxsxrs
link
考慮倍增分塊,底數為 \(b\),將 \([b^i, b^{i + 1} )\) 分為一塊。對於每個塊,開一棵線段樹,便於找到需要修改的數。線段樹需要維護屬於塊內的,區間最小值,區間最大值,數字個數,以及這些數的總和。當一個數跌落出其所在塊時,暴力 update。
一個數在同一塊內至多被修改 \(b\) 次,至多跌落 \(\log_b a_i\) 次,每次修改都要 \(\mathcal O(\log_2 n)\) 複雜度,總時間複雜度為 \(\mathcal O(nb\log_ba_i\log_2n)\)。
空間較緊,可以底層分塊,線段樹只維護塊間的資訊。當塊長取 \(\mathcal O(\log_2n)\) 時,複雜度不變,空間為 \(\mathcal O(\dfrac {n \log_b a_i } {\log_2 n})\)。
- 啟示:倍增分塊有利於數值的比較;底層分塊。
「THUPC 2022」rsraogps
link
先離線掃描線,設 \(a'_j,b'_j,c'_j\) 分別為 \([j, i]\) 的三個結果。
-
Observe 1:每次新加入的 \(i\) 會影響的 \(j\) 只會是一段字尾。
-
Observe 2:\((a'_j, b'_j, c'_j)\) 被更新的次數為 \(\mathcal O(\log V)\)。
直接暴力修改,維護歷史和即可。
- 啟示:時間複雜度分析;觀察維護的資訊的特點。