【題解】Solution Set - NOIP2024集訓Day12 樹上啟發式合併
https://www.becoder.com.cn/contest/5472
「CF600E」Lomsat gelral
直接 dsu on tree。記錄每一個顏色的出現次數。
「IOI2011」Race
之前是用點分治做的。
考慮 dsu on tree。每個子樹內維護到根節點的距離為 \(x\) 的最短條數(就是最小深度。
然後加入輕兒子的時候更新當前答案就行了。
因為我們優先計算輕兒子的答案,所以在清空當前子樹的影響的時候,可以直接全部清除。
「CF375D」Tree and Queries
比較暴力的兩隻 \(\log\) 的 dsu on tree 做法,是再用一個線段樹維護每個 \(cnt\) 有多少個。
線段樹合併的做法,就是再用一個線段樹維護 \(cnt\),這樣就做到了單 \(\log\)。
現在再來仔細想一想單 \(\log\) 的 dsu on tree 的做法。
考慮到每次 \(cnt\) 最多隻會 \(\pm 1\),我們就可以 \(O(1)\) 維護大於等於 \(k\) 的個數有多少個。
「CF715C」Digit Tree
一眼推式子題。(下面的運算都在模 \(m\) 的意義下進行。
\[\sum_{i=1}^{len} w_i\times 10^i\equiv 0\pmod m
\]
還是 不太好做。😅
考慮維護每個點到根節點組成的所構成的數字 \(f_i\),根節點到每個點組成的所構成的數字 \(g_i\)。
(根節點的 \(dep\) 為 \(0\)。
\[\text{lca}(u,v)=d\\
Ans(u,v)=(f_u-f_d)\times 10^{-dep_d}\times 10^{dep_v-dep_d}+(g_v-g_d\times 10^{dep_v-dep_d})
\]
對於加入的點作為開頭,查詢點作為結尾(加入左邊,查詢右邊。
\[f_u =-(g_v-g_d\times 10^{dep_v-dep_d})\times 10^{2dep_d-dep_v} + f_d
\]
對於加入的點作為結尾,查詢點作為開頭(加入左邊,查詢右邊。
\[g_v\times 10^{-dep_v}=-(f_u-f_d)\times 10^{-2dep_d}+g_d\times 10^{dep_v-dep_d}a
\]
其實感覺一般的 dsu on tree。
難點就在於選好在 ds(一般是桶)裡面維護什麼,以及查詢什麼。並且能夠滿足全域性的性質(不能因為根節點的改變而改變的量,比如到當前子樹的根的距離)
跟當前子樹的根有關的變數都放在查詢那邊。