高维前缀和学习小记

问题引入:

现有 a [ i ] ( 0 &lt; = i &lt; 2 n ) a[i](0&lt;=i&lt;2^n) a[i](0<=i<2n)
对于每一 i i i,求 ∑ j ∈ i a [ j ] \sum_{j∈i}a[j] jia[j]
这里的 ∈ ∈ 指二进制状态下的被包含。

暴力解决问题:

即暴力枚举子集求和。
复杂度计算:

∑ i = 0 n C n i ∗ 2 i \sum_{i=0}^nC_{n}^i*2^i i=0nCni2i

= ∑ i = 0 n C n i ∗ 2 i ∗ 1 n − i =\sum_{i=0}^nC_{n}^i*2^i*1^{n-i} =i=0nCni2i1ni

= ( 1 + 2 ) n =(1+2)^n =(1+2)n

动态规划:

考虑对于一个 i i i,枚举把一个0变成1,转移上去。

但是这样显然会有重。

比如说 i = 0 i=0 i=0
第一轮加上 2 0 2^0 20,第二轮加上了 2 1 2^1 21

也可以第一轮加上 2 1 2^1 21,第二轮加上 2 0 2^0 20

这样就会重复。

那么考虑使增加的1的位置递增的。

f i , j f_{i,j} fi,j表示到 i i i了,上一次增加的1是第 j j j位上的。

那么枚举 k ( ( k &gt; = j )   a n d   ( i 的 第 k 位 是 0 ) ) k((k&gt;=j)~and~(i的第k位是0)) k((k>=j) and (ik0)) f ( i ∣ 2 k , k ) + = f ( i , j ) f(i|2^k,k)+=f(i,j) f(i2k,k)+=f(i,j)

这样的复杂度是 O ( 2 n ∗ n 2 ) O(2^n*n^2) O(2nn2)

对于上面的式子可以前缀和优化:
f ( i , j ) + = f ( i , j − 1 ) , f ( i ∣ 2 j , j ) + = f ( i , j ) ( i 的 第 j 位 是 0 ) f(i,j)+=f(i,j-1),f(i|2^j,j)+=f(i,j)(i的第j位是0) f(i,j)+=f(i,j1),f(i2j,j)+=f(i,j)(ij0)

复杂度 O ( 2 n ∗ n ) O(2^n*n) O(2nn)

正题:

把上述问题看作一个n维空间,每一维坐标的范围是 [ 0..1 ] [0..1] [0..1],求前缀和。

考虑二维暴力是怎么做的(不差分)?

先一行一行的扫描,记录下来和,然后再一列一列的扫描。

高维同理,就是一维一维的扫描。

下面给出代码实现:

fo(j, 0, N - 1) fo(i, 0, (1 << N) - 1)
		if(i >> j & 1) a[i] += a[i ^ (1 << j)];

复杂度 O ( 2 n ∗ n ) O(2^n*n) O(2nn)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值