1. 程式人生 > >Codechef WEASELTX

Codechef WEASELTX

情況 mod problem .com 操作 初始 pro 合並 amp

WEASELTX code
給你一棵 n 個節點的有根樹(節點),以及每個節點 i 的初始權值 a[i] 。
一次操作則是指將每個節點的權值變為以其為根的子樹中所有節點的權值之異或和。
維護 q 個詢問,每個詢問則是問 T 次操作之後,根節點的權值。
解:
相關題目:HDU 6129 http://acm.hdu.edu.cn/showproblem.php?pid=6129
HDU 6129 是樹退化成一條鏈的情形。

我們的做法依然是考慮每個節點對答案的貢獻。
如果是求和,則 T 次操作之後,考慮每個節點 i 對答案的貢獻,結果為
$$\sum_{i} \binom{T+d[i]-1}{d[i]} a[i],$$
其中 d[i] 是節點 i 的深度(根節點深度為 0 ),額外定義$\binom{-1}{0} = 1$。

而對於異或和,我們只需要考慮系數模 2 的余數即可,上式可變為
$$\bigoplus_{i} \left( \binom{T+d[i]-1}{d[i]} \bmod 2 \right) a[i].$$

剩下我們要考慮 $\binom{a+b}{b} \bmod 2 = 1$ 的充要條件。
由 Lucas 定理,可得 $\binom{a}{b} \bmod 2 = 1$ 當且僅當 $a \operatorname{and} b = b$ 。
從而,$\binom{a+b}{b} \bmod 2 = 1$ 當且僅當 $(a+b) \operatorname{and} b = b$ ,即$a \operatorname{and} b = 0$(不是那麽顯然,需要讀者自行證一下)。

觀察式子可以發現,設$2^k > \max_i \{d[i]\}$,則 $T$ 次操作後的結果與 $T \bmod 2^k$ 次操作後的結果相同。
因此我們可以只考慮 $0 \le T < 2^k$ 的情況。

註意到 $\binom{T+d[i]-1}{d[i]} \bmod 2 = 1$ 當且僅當 $(T-1) \operatorname{and} d[i] = 0$。
於是我們先把所有節點按照其深度分組,同一個深度的節點先合並在一塊,因為他們在參與運算時一定是捆綁在一起的。
接著根據 $(T-1)$,我們依次枚舉滿足條件的 $d[i]$ ,這是一個經典的子集枚舉,即枚舉 ~(T-1) 的子集。
枚舉 s 的子集的方式為

for (int x = s; x; x = (x-1)&s)
{
    // we have enumerated every x satisfying x&s = x.
}

由於 T 會取遍 $[0, 2^k)$ 之間的值,這樣對每個 T 都枚舉一遍子集的時間復雜度為 $O(3^k)$ (不是那麽顯然,需要讀者自行證明)。
而 $k = O(\log n)$,於是,總的時間復雜度為 $ O(3^{\log n}) $。

Codechef WEASELTX