1. 程式人生 > 其它 >LOJ6733 人造情感 / 3.14 校內考試 靈活性(flexibility)

LOJ6733 人造情感 / 3.14 校內考試 靈活性(flexibility)

給你一顆 \(n\) 個節點的樹,以及 \(m\) 條路徑 \((u, v, w)\),其中 \(w\) 可以認為是 \((u, v)\) 這題路徑被標記的一個權值。一個路徑集合 \(S\) 的重量 \(W(S)\) 記為:找出 \(S\) 的一個權值之和最大的子集,該子集滿足任何兩條路徑沒有公共點,這個子集的所有路徑權值之和就是 \(W(S)\)

\(f(u, v) = w\) 為最小的非負整數 \(w\),使得對於給定的 \(m\) 條邊組成的路徑集合 \(U\)\(W(U \cup \{(u, v, w + 1)\}) > W(U)\)

請你計算下式,對 \(998244353\)

取模。

\[\sum_{u=1}^n \sum_{v=1}^n f(u, v) \]

\(n \le 3 \times 10^5, 0 \le m \le 3\times 10^5, 1 \le w \le10^9\)


  資料結構 動態規劃

  首先考慮怎麼計算 \(W(U)\),我們可以設 \(f(x)\) 表示僅考慮 \(x\) 為根的子樹,不管 \(x\) 的選擇情況的最大權值,\(g(x)\) 表示僅考慮 \(x\) 為根的子樹,\(x\) 必須是空的收益,然後我們可以設 \(c(x) = g(x) - f(x)\) 表示把 \(x\) 空出來的代價,然後有轉移:

\[\begin{cases} g(x) = \sum_{y \in son_x} f(x)\\ f(x) = g(x) + \max_{\mathrm{lca}(u_i, v_i) = x}\{\sum_{k \in \mathrm{path}(u_i, v_i)} c_k\} \cup \{0\} \end{cases} \]

  然後 \(c(x)\)

可以理解為加上 \(c(x)\)\(f(x)\) 就是 \(\sum_{y \in son_x} f_y\) 了,於是 \(x\) 不選了。

  接著考慮 \(W(U \cup \{u, v, w +1\})\) 怎麼求,那麼如果 \(\mathrm{lca}(u, v) = 1\),那麼答案就是 $f(1)+ \sum_{k \in \mathrm{path}(u, v)} c_k $。

  但是如果不滿足上面的條件,令 \(t = \mathrm{lca}(u, v)\),那麼就可能會存在一條路徑使得其從上面經過了 \(t\),然後我們要將貢獻消除,於是我們可以設 \(h(x)\)

表示對於不存在從 \(x\) 父親到 \(x\) 子樹的路徑被選的情況下,\(f(1)\) 的最大值,假設當前考慮的節點為 \(x\),那麼有轉移(預設轉移是取 \(\max\)):

\[\begin{cases} h(y) \gets h(x) + c(x), &y \in son_x\\ h(y) \gets h(x) + \sum_{k\in \mathrm{path}(u_i, v_i)} c_k + w_i, &\mathrm{lca}(u_i, v_i) = x, y \not\in \mathrm{path}(u_i, v_i), fa_y \in \mathrm{path}(u_i, v_i) \end{cases} \]

  第一個轉移顯然可以直接賦值,第二個轉移,我們要考慮在一條路徑 \((u_i, v_i)\) 上面打上 \(h(x) + \sum_{k\in \mathrm{path}(u_i, v_i)} c_k + w_i\) 的標記,然後將它傳下去取 \(\max\),同時有不能傳到路徑上面的點。

  如果是暴力,可以考慮每個點維護一個 tuple(w, a, b) 表示權值為 \(w\)tag,並且不能傳到 \(a, b\) 兩個兒子(如果沒有這麼多限制,直接賦值為 \(0\) 即可),然後將所有標記 sort 一遍,對於每個點暴力從大到小掃一遍,直到找到第一個滿足條件的最大的,因為每個標記最多被掃到 \(2\) 遍,因此複雜度為 \(\mathcal O(\sum 標記之和)\) 的。

  然後我們可以使用線段樹 + 樹剖優化這個過程,因為很多標記都是賦值為 \((w, 重兒子, 0)\) 的形式,因此可以樹剖維護對於每個點,這種標記的最大值(也就是這種標記中只取最大的一個),每次操作只有重鏈頂端要單獨賦值,於是總的標記個數就是 \(\mathcal O(m \log n + n)\) 的了。

  求出 \(h(x)\) 之後,對於 \((u, v)\) 的答案就是 \(f(1) - \left(h(\mathrm{lca}(u, v)) + \sum_{k \in \mathrm{path}(u, v)} c_k\right)\) 了,後面的式子就是在滿足 \(\{u, v \}\) 所在聯通塊沒有被佔領的情況下的最大值,那麼答案就是這個式子了。

  具體細節看程式碼