Codechef WEASELTX

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} inom{T+d[i]-1}{d[i]} a[i],$$
其中 d[i] 是节点 i 的深度(根节点深度为 0 ),额外定义$inom{-1}{0} = 1$。

而对于异或和,我们只需要考虑系数模 2 的余数即可,上式可变为
$$igoplus_{i} left( inom{T+d[i]-1}{d[i]} mod 2 ight) a[i].$$

剩下我们要考虑 $inom{a+b}{b} mod 2 = 1$ 的充要条件。
由 Lucas 定理,可得 $inom{a}{b} mod 2 = 1$ 当且仅当 $a operatorname{and} b = b$ 。
从而,$inom{a+b}{b} mod 2 = 1$ 当且仅当 $(a+b) operatorname{and} b = b$ ,即$a operatorname{and} b = 0$(不是那么显然,需要读者自行证一下)。

观察式子可以发现,设$2^k > max_i {d[i]}$,则 $T$ 次操作后的结果与 $T mod 2^k$ 次操作后的结果相同。
因此我们可以只考虑 $0 le T < 2^k$ 的情况。

注意到 $inom{T+d[i]-1}{d[i]} mod 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}) $。

原文地址:https://www.cnblogs.com/TinyWong/p/7478598.html