高维前缀和(后缀和)

高维前缀和(后缀和)

Method1

可以直接容斥, 式子形如 :

\(f_{a, b} = f_{a - 1, b} + f_{a, b - 1} - f_{a - 1, b - 1} + g_{a, b}\)

\(f_{a, b, c} = f_{a - 1, b, c} + f_{a, b - 1, c} + f_{a, b, c - 1} - f_{a - 1, b - 1, c} - f_{a - 1, b, c - 1} - f_{a, b - 1, c - 1} + f_{a - 1, b - 1, c - 1} + g_{a, b, c}\)

\(f_{a, b, c, d} = f_{a - 1, b, c, d} + ... - f_{a - 1, b - 1, c, d} - ... + f_{a - 1, b - 1, c - 1, d} + ... - f_{a - 1, b - 1, c - 1, d - 1} + g_{a, b, c, d}\)

如果由前缀和(后缀和)逆推的话, 式子(也许)差不多吧

这样子的做的时间复杂度是 \(O(n^t2^t)\) 的 (t 为维数, 一次容斥的时间复杂度为 \(2^t\))

Method2

分别对于每一维求一次前(后)缀和, 例如三维前缀和 :

fo(i, 1, n) fo(j, 1, n) fo(k, 1, n)
    f[i][j][k] += f[i][j][k - 1];
fo(i, 1, n) fo(j, 1, n) fo(k, 1, n)
    f[i][j][k] += f[i][j - 1][k];
fo(i, 1, n) fo(j, 1, n) fo(k, 1, n)
    f[i][j][k] += f[i - 1][j][k];

这样子写虽然看似比较繁琐, 但是时间复杂度仅为 \(O(tn^t)\)

逆推的话也十分简单, 基本就是把上边过程反过来即可

posted @ 2020-10-28 21:45  buzzhou  阅读(298)  评论(0编辑  收藏  举报