2次元累積和

概要

$H$行$W$列の行列があり,各要素を$A_{ij}$とする.このとき,前処理を行うことで,次の値を$O(1)$で求めることができる. $$ \sum_{h_1\leq i< h_2}\sum_{w_1\leq j<w_2} A_{ij} $$

計算量

  • 構築: $O(HW)$
  • クエリ: $O(1)$

ソースコード

template<class T> struct CumulativeSum2D{
    size_t H,W;
    vector<vector<T>>data,A;
    CumulativeSum2D(size_t H,size_t W){
        this->H=H;
        this->W=W;
        data.resize(H+1,vector<T>(W+1,0));
        A.resize(H+1,vector<T>(W+1,0));
    }
    void add(size_t h,size_t w,T x){
        A[h][w]+=x;
    }
    void build(){
        int H=A.size();
        int W=A[0].size();
        data=vector<vector<T>>(H+1,vector<T>(W+1,0));
        rep(i,H){
            rep(j,W){
                data[i+1][j+1]=A[i][j];
            }
        }
        rep(i,H+1){
            rep(j,W){
                data[i][j+1]+=data[i][j];
            }
        }
        rep(i,H){
            rep(j,W+1){
                data[i+1][j]+=data[i][j];
            }
        }
    }
    /*w1<=x<w2, h1<=y<h2*/
    T sum(int h1,int w1,int h2,int w2){
        return data[h2][w2]-data[h1][w2]-data[h2][w1]+data[h1][w1];
    }
};