zoukankan      html  css  js  c++  java
  • 高维前缀和 学习笔记

    其实是个异常简单的东西……

    众所周知,一维前缀和是 (mathrm O(n)) 的,二维前缀和是 (mathrm O!left(n^2 ight))(这里假定各维度值域相等)的。那么 (d) 维前缀和(这个唤做高维前缀和)就是 (mathrm O!left(n^d ight)) 的?显然做不到。这是因为一、二维前缀和常数可以忽略。

    那么被忽略掉的常数显然等于计算一个值的时候的式子的项数,一维是 (2),二维是 (4)。维数多了以后,你会发现这个常数就是一个 (d) 维超立方的顶点数,显然是 (2^d)。于是 (d) 维前缀和的暴力算法就是 (mathrm O!left(2^dn^d ight))

    我们常遇到这样的问题:在 (2^d) 的个 bitmask 上有一些数,求每个 bitmask 的子集和。这可以看作一个 (n=2) 的高维前缀和问题。按上面说的算法是 (mathrm O!left(4^d ight)) 的,由于这里 (n=2) 的特殊性,我们可以枚举子集做到 (mathrm O!left(3^d ight))。是否有更优秀的方法呢?

    我们考虑换一种求高维前缀的思路,考虑一维一维的推。先算出在每个位置算出第 (2sim d) 维固定,第 (1) 维的前缀和;再算出第 (3sim d) 维固定,第 (1sim 2) 维的前缀和,这个显然是前面那个一维前缀和的前缀和;以此类推,最后可以求出 (d) 维前缀和。脑子里面可以脑补一下这个 gif。所以复杂度是 (mathrm O!left(dn^d ight))(n=2) 时就是 (mathrm O!left(2^dd ight))

    然后众所周知前缀和的逆运算为差分,考虑如何计算高维差分(不知道这个东西有没有用)?只需要一维一维算差分即可,这个可能没有什么好理解的数学证明方法,但你可以从高维往低维再对它做高维前缀和运算,发现正好抵消掉了,而高维前缀和显然是维度顺序无关的。

    但是不知道有没有 (mathrm O(d)) 查超立方和或者 (mathrm O(d)) 超立方加?可能没有,可能有,有的话肯定也不属于高维前缀和的范畴了。

    upd 2020.12.15:其动态做法

    我们考虑这样一个问题:求 (f:f_i=a_i+sumlimits_{jsubsetneq i}f_j)。这显然是需要动态维护高维前缀和数组的。但是上面说的方法只能静态。

    注意到上述高维前缀和过程其实是这样一个 DP:(Sum_{i,j}) 表示值 (i)(j) 维前缀和,那么转移就是上一个值的 (j) 维前缀和加上当前值的 (j-1) 维前缀和。显然关于 (i)(j) 的两层循环哪层在外无所谓,因为关于哪一维都是无后效性的。上述高维前缀和求法本质上就是这个 DP 的外层为 (j) 的转移顺序,然后因为每个阶段只可能转移到上一个阶段,所以可以省略掉 (j) 这一维。而局限性就在于无法动态。

    动态的呢,动态过程显然是按照 (i) 在外枚举的,那这时候就省不掉维了。乖乖 DP 就好了,复杂度不变。

    动态高维差分就一个道理啦。

    例题

    CF449D - Jzzhu and Numbers

    容斥 + 高维前缀和一般题(ymx 附体)

    选的一个集合满足条件,显然当且仅当每一位都有人是 (0)。于是我们考虑每个数能够满足哪些位(就是取反)。

    考虑反面考虑,求至少有一位没有被满足的方案数。这样就可以很舒服的容斥了。于是现在只要求对于任意 bitmask (x)(x) 内的位不被满足,其他位随便的方案数。这显然就是只有 (x) 的补 bitmask 的子集才能选,而且任意一种选的方案都是可以的,那么设 (x) 的补 bitmask 的子集中有 (cnt) 个给定的,那么它对答案的贡献就是 (2^{cnt}) 乘以容斥系数。

    那么问题就成了求对于所有 bitmask,求出他的被给定的子集数。那这不就是个高维前缀和板子嘛?

    code

    CF76C - Mutation

    题解

    ARC100C - Or Plus Max

    考虑对于每个 (K) 求出下标为 (K) 子集的最大 (a_i+a_j)。那么显然一个是最大值,一个是次大值,这个是高维前缀和(前缀最值、次值)可以轻松计算的。

    但这样子是假的,因为 (leq K) 不等于是 (K) 的子集。但很显然是 (leq K) 的所有数的子集的并。于是按原先算法算出来答案后取个前缀 (max) 即可。

    珍爱生命,远离抄袭!
  • 相关阅读:
    sql 数据库还原脚本 (kill链接+独占
    最长回文字符串
    UVa 455 Periodic Strings
    UVa 1225 Digit Counting
    UVa 340 Master-Mind Hints
    UVa 10976
    UVa 725
    UVa 11059
    POJ1887 最长下降子序列
    最大连续子序列算法(数组的连续子数组最大和(首尾不相连))
  • 原文地址:https://www.cnblogs.com/ycx-akioi/p/gwqzh.html
Copyright © 2011-2022 走看看