求
\[\sum_^ [i\ \&\ n = i] a_i
\](實際上, 這只是高維字首和的一種特殊形式, 即每一維的大小都為 2.)
我們計算矩陣字首和時, 通常用的是容斥的方法.
設當前要計算 \(d\) 維字首和, 容斥的複雜度為
\[\sum_^n \binom = 2^d
\]當維數過大時顯然不行.
我們考慮計算矩陣字首和的另一種方法 : 先算出每一列的字首和, 然後再把每一列的字首和加起來即可得到乙個矩陣的字首和.
我們來分析一下這個方法的實質 : 矩陣是乙個二維結構, 我們用二元組 \((i,j)\) 來表示矩陣上的點. 那麼每一列的字首和實質上是控制了 \(j\) 這一維後計算的字首和, 而乙個矩陣的字首和就是 \(i,j\) 這兩維都不進行控制的字首和.
考慮把這個方法推廣到 \(d\) 維 : 先求出控制 前 \(d\) 維 的字首和, 再求出控制 前 \(d - 1\) 維 的字首和, 再求出控制 前 \(d - 2\) 維的字首和 ...... 最終求出控制 前 \(0\) 維 的字首和, 即為 \(d\) 維字首和.
用式子來表示就是 : 設 \(sum[i][s]\) 為控制了 前 \(d - i\) 維的點 \(s\) 的字首和 (即 \(sum[i][s]\) 內統計到的點的 前 \(d - i\) 維 都和 \(s\) 相同), 那麼 \(sum[i][s] = sum[i - 1][s] + sum[i][s']\), 其中 \(s'\) 為前 \(i - 1\) 維都與 \(s\) 相同 且 第 \(i\) 維比 \(s\) 小 \(1\) 的點. 聯想一下矩陣字首和就很好理解了.
由於在轉移過程中, \(s'\) 嚴格小於 \(s\), 所以 \(sum\) 的第一維可以用滾動陣列優化.
這裡只給出了每一維的大小都等於 \(2\) 的情況的**, 即「演算法用途」中給出的形式.
for (int i = 0; i < n; i++)
for (int s = 0; s < 1 << n; s++)
if (s >> i & 1) sum[s] += sum[s ^ (1 << i)];
sosdp(高維字首和)學習筆記
我們先看一維字首和 for int i 1 i n i s i s i 1 那麼二維字首和 for int i 1 i n i for int j 1 j n j s i j s i 1 j s i j 1 s i 1 j 1 這個是根據容斥計算的,維度很高的時候就不行了 我們換一種方法 for i...
高維字首和
給定 num 個三元組 x,y,z 每次詢問滿足 x leq qx y leq qy z leq qz 的三元組個數。x,y,z leq n n leq 10 q num leq 10 6 容易想到維護 pre x,y,z 表示 x leq x y leq y z leq z 的三元組個數 思路1利...
hihocoder1496(高維字首和)
題意 給定n個數a1,a2,a3,an,小ho想從中找到兩個數ai和aj i j 使得乘積ai aj ai and aj 最大。其中and是按位與操作。第一行乙個整數n 1 n 100,000 第二行n個整數a1,a2,a3,an 0 ai 2 20 分析 嘗試列舉and值z,那麼問題就變成了找尋最...