1. 程式人生 > 其它 >最近一些題的題解

最近一些題的題解

1. 摩爾莊園

用樹形 dp 模擬網路流。

\(a\)\(x\) 走向 \(fa(x)\) 的次數,\(b\)\(fa(x)\) 走向 \(x\) 的次數,\(flw(x) = a - b\)

這樣在從 \(x\) 走向 \(fa\) 時:

  • 如果 \(flw(x) < 0\),表示有更多次從 \(fa\) 走向 \(x\),那麼這一次費用為 \(-1\),表示和之前一次從 \(fa\) 走向 \(x\) 的費用抵消了(網路流的思路)。
  • 否則,無法抵消,費用為 \(1\)

\(fa\) 走向 \(x\) 時是類似的。

從下往上進行 \(\rm Update\),計算從 \(x\)

到其子樹中有食物的地方,費用最小是多少,並記錄下那個點的編號。

每讀入一隻拉姆的位置,就計算其費用並更新圖中的費用。

Code

2. Centroids

CF708C Centroids

一個優秀的性質是以重心為根時所有點的子樹大小都不會超過 \(\dfrac{n}{2}\),因為根本身就是如此。

對於節點 \(u\),這時只有 \(u\) 上面的部分有可能超過 \(\dfrac{n}{2}\),那麼最優策略是選擇其中最大的不超過 \(\dfrac{n}{2}\) 的子樹,把它接到 \(u\) 上,設這一部分的大小為 \(cut_u\),那麼剩下的部分就是 \(n - siz_u - cut_u\)

,如果仍然大於 \(\dfrac{n}{2}\),那麼無法成為重心;否則可以。

於是問題轉為如何求 \(cut_u\)

記錄 \(mx_u\)\(u\) 子樹內(不包括 \(u\))最大的不超過 \(\dfrac{n}{2}\) 的子樹大小,當從 \(u\) 轉移到 \(v\) 時:

\[cut_u = \cases { \max(cut_u, n - siz_u), n - siz_u \le \dfrac{n}{2} \\ cut_u, \rm otherwise } \\ cut_v = \max(cut_u, mx_u) \]

但如果 \(v\) 的子樹就是 \(u\) 的最大的不超過 \(\dfrac{n}{2}\)

的子樹,這時 \(mx_u\) 是不能選的,所以我們應該記錄最大值和次大值 \(mx_{u,0}, mx_{u, 1}\)。這樣轉移就變成了

\[cnt_v = \cases { \max(cut_u, mx_{u, 0}), siz_v \ne mx_{u, 0} \\ \max(cut_u, mx_{u, 1}), siz_v = mx_{u, 0} } \]

Code

3. 由乃與大母神原型和偶像崇拜

P3792 由乃與大母神原型和偶像崇拜

發現 \(n\) 個數的和容易重,但平方和就不好重。所以維護區間最小 \(mn\)、區間最大 \(mx\)、區間和 \(sum1\)、區間平方和 \(sum2\)

首先判斷 \(mn + len - 1\) 是否等於 \(mx\),然後求 \(\sum\limits_{i = mn}^{mx} i\) 是否等於 \(sum1\)\(\sum\limits_{i = mn}^{mx}i ^2\) 是否等於 \(sum2\)

模數直接 $\rm unsigned\ long\ long $ 自然溢位,注意等差數列與平方和都要除一個數,把它乘到式子另一邊去。

當然你怕不保險也可以加上立方和,這樣就幾乎卡不掉了(

Code