【高维前缀和】FMT变换-高维前缀和

学习自该位大神的博客--高维前缀和

大致就是我们考虑高维前缀和的时候,朴素的想法是通过容斥原理求前缀和,在维数较高时不可取。故,我们采取用

for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
        a[i][j]+=a[i][j-1];
for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
        a[i][j]+=a[i-1][j];

类似这样的方法,考虑一下过程就是先求一行的前缀和再求一列的前缀和,这样就求到了每一维都比它低的和,即高维前缀和。

牛客 部分和

一道例题,具体到二进制上一个数所有子集的和传统而言是3^n的,采用高维前缀和,即每个维度长为2,那么就是2^n*n

查看代码

#include <bits/stdc++.h>

using namespace std;
const int maxn = (1 << 20);
int n;
int a[maxn];
int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    for (int wei = 0; wei < 20; wei++) {
        for (int i = 0; i < n; i++) {
            if ((1 << wei) & i) {
                a[i] += a[i ^ (1 << wei)];
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%d\n", a[i]);
    }
    return 0;
}
posted @ 2022-03-01 21:15  Newuser233  阅读(34)  评论(0编辑  收藏  举报