1. 程式人生 > 其它 >【高維字首和】FMT變換-高維字首和

【高維字首和】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;
}