CF772D - Varying Kibibits 题解

显然要算出每个 \(G(x)\)。注意到,仅当 \(x'\) 的每一位都 \(\geq\) \(x\) 的每一位,\(x'\) 才可能被包含在 \(f(S)=x\)\(S\) 里。然后如果满足这样条件的 \(S\) 会有 \(f(S)\) 的每一位都 \(\geq\) \(x\) 的每一位,那么可以先求出这样的 \(S\) 的和平方和,然后 \(\dfrac{G(x)}x\) 就高维差分一下即可得到(非 bitmask 的高维差分 / 前缀和啊,刺激)(注意一点:这时候高维差分的循环顺序也要反向,之前写的都是 bitmask 的高维差分,不反向依然是对的,所以一直没发现错误)。

然后我们考虑如何求,对 \(m\) 个数的集合组成的 \(2^m\) 个子集的和平方和该如何求。每个 \(m\) 个数的集合都是每一位 \(\geq\) 某个数的每一位的所有数组成的集合,有高维后缀和内味了。那么我们考虑,对于两个集合,该如何合并它们。

先考虑和零次方和,那显然就乘起来即可。然后是和一次方和(和的和),那么我们还须要记录两个集合的子集个数(\(2^?\)),然后配合和的和算出来合并起来的结果。到这里都是我们一般做的题目的样子,非常自然。

那么和二次方和该如何求呢?我们考虑列式计算:\(\sum\sum(x+y)^2=\sum\sum\left(x^2+2xy+y^2\right)=\sum y^0\sum x^2+2\sum x^1\sum y^1+\sum x^2\sum y^0\)。那么我们需要记录两个集合的和 \(0\sim 2\) 次方和。那么我们考虑将和 \(0\sim 2\) 次方和作为一个整体的元素(struct 实现将会异常方便),定义它们之间的二元合并运算,它显然是运算律什么的都满足的。事实上次数更高的话,可以用二项式定理展开。

得出结论:这是一个非二进制高维前缀和 & 差分 与 二项式定理维护和的低次方的套路 的缝合怪。

code

posted @ 2020-12-26 17:01  ycx060617  阅读(107)  评论(0编辑  收藏  举报