Procon

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub K-Yoshizawa/Procon

:heavy_check_mark: Cumulative Sum 2D - 二次元累積和
(Library/DataStructure/CumulativeSum2D.hpp)

Cumulative Sum 2D - 二次元累積和

$H \times W$ の二次元配列 $A$ に対し、長方形領域の総和を効率的に計算するデータ構造です。

Function

Constructor

CumulativeSum2D(const int height, const int width, const T init_value = 0)

制約

計算量


Set

void Set(const int y, const int x, const T value)

制約

計算量


Add (一点加算)

void Add(const int y, const int x, const T value)

制約

計算量


Add (領域加算)

void Add(const int y1, const int x1, const int y2, const int x2, const T value)

制約

計算量


Build

void Build()

計算量


Sum (矩形領域)

(1) T Sum(const int y, const int x) const
(2) T Sum(const int y1, const int x1, const int y2, const int x2) const

制約

計算量


Max

T Max() const

計算量


Min

T Min() const

計算量


operator[]

vector<T> &operator[](const int k)

制約

計算量


Depends on

Verified with

Code

#include "../Common.hpp"

template<typename T = int32_t>
struct CumulativeSum2D{
    private:
    int height_, width_;
    vector<vector<T>> data_;

    void Validate(const int y, const int x) const {
        assert(0 <= y && y < height_ - 1);
        assert(0 <= x && x < width_ - 1);
    }

    public:
    CumulativeSum2D(const int height, const int width, const T init_value = 0) : height_(height + 1), width_(width + 1){
        data_.resize(height_);
        for(int i = 0; i < height_; ++i){
            data_.at(i).resize(width_, init_value);
        }
    }

    void Build(){
        for(int i = 1; i < height_; ++i){
            for(int j = 0; j < width_; ++j){
                data_[i][j] += data_[i - 1][j];
            }
        }
        for(int i = 0; i < height_; ++i){
            for(int j = 1; j < width_; ++j){
                data_[i][j] += data_[i][j - 1];
            }
        }
    }

    void Set(const int y, const int x, const T value){
        Validate(y, x);
        data_[y][x] = value;
    }

    void Add(const int y, const int x, const T value){
        Add(y, x, y, x, value);
    }

    void Add(const int y1, const int x1, const int y2, const int x2, const T value){
        Validate(y1, x1);
        Validate(y2, x2);
        data_[y1][x1] += value;
        data_[y2 + 1][x1] -= value;
        data_[y1][x2 + 1] -= value;
        data_[y2 + 1][x2 + 1] += value;
    }

    T Sum(const int y, const int x) const {
        Validate(y, x);
        return data_[y][x];
    }

    T Sum(const int y1, const int x1, const int y2, const int x2) const {
        Validate(y1, x1);
        Validate(y2, x2);
        T ret = Sum(y2, x2);
        if(y1 > 0) ret -= Sum(y1 - 1, x2);
        if(x1 > 0) ret -= Sum(y2, x1 - 1);
        if(y1 > 0 && x1 > 0) ret += Sum(y1 - 1, x1 - 1);
        return ret;
    }

    T Max() const {
        T ret = data_[0][0];
        for(int i = 0; i < height_; ++i){
            for(int j = 0; j < width_; ++j){
                ret = max(ret, data_[i][j]);
            }
        }
        return ret;
    }

    T Min() const {
        T ret = data_[0][0];
        for(int i = 0; i < height_; ++i){
            for(int j = 0; j < width_; ++j){
                ret = min(ret, data_[i][j]);
            }
        }
        return ret;
    }

    vector<T> &operator[](const int k){
        return data_.at(k);
    }
};
#line 2 "Library/Common.hpp"

/**
 * @file Common.hpp
 */

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cstdint>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

using ll = int64_t;
using ull = uint64_t;

constexpr const ll INF = (1LL << 62) - (3LL << 30) - 1;
#line 2 "Library/DataStructure/CumulativeSum2D.hpp"

template<typename T = int32_t>
struct CumulativeSum2D{
    private:
    int height_, width_;
    vector<vector<T>> data_;

    void Validate(const int y, const int x) const {
        assert(0 <= y && y < height_ - 1);
        assert(0 <= x && x < width_ - 1);
    }

    public:
    CumulativeSum2D(const int height, const int width, const T init_value = 0) : height_(height + 1), width_(width + 1){
        data_.resize(height_);
        for(int i = 0; i < height_; ++i){
            data_.at(i).resize(width_, init_value);
        }
    }

    void Build(){
        for(int i = 1; i < height_; ++i){
            for(int j = 0; j < width_; ++j){
                data_[i][j] += data_[i - 1][j];
            }
        }
        for(int i = 0; i < height_; ++i){
            for(int j = 1; j < width_; ++j){
                data_[i][j] += data_[i][j - 1];
            }
        }
    }

    void Set(const int y, const int x, const T value){
        Validate(y, x);
        data_[y][x] = value;
    }

    void Add(const int y, const int x, const T value){
        Add(y, x, y, x, value);
    }

    void Add(const int y1, const int x1, const int y2, const int x2, const T value){
        Validate(y1, x1);
        Validate(y2, x2);
        data_[y1][x1] += value;
        data_[y2 + 1][x1] -= value;
        data_[y1][x2 + 1] -= value;
        data_[y2 + 1][x2 + 1] += value;
    }

    T Sum(const int y, const int x) const {
        Validate(y, x);
        return data_[y][x];
    }

    T Sum(const int y1, const int x1, const int y2, const int x2) const {
        Validate(y1, x1);
        Validate(y2, x2);
        T ret = Sum(y2, x2);
        if(y1 > 0) ret -= Sum(y1 - 1, x2);
        if(x1 > 0) ret -= Sum(y2, x1 - 1);
        if(y1 > 0 && x1 > 0) ret += Sum(y1 - 1, x1 - 1);
        return ret;
    }

    T Max() const {
        T ret = data_[0][0];
        for(int i = 0; i < height_; ++i){
            for(int j = 0; j < width_; ++j){
                ret = max(ret, data_[i][j]);
            }
        }
        return ret;
    }

    T Min() const {
        T ret = data_[0][0];
        for(int i = 0; i < height_; ++i){
            for(int j = 0; j < width_; ++j){
                ret = min(ret, data_[i][j]);
            }
        }
        return ret;
    }

    vector<T> &operator[](const int k){
        return data_.at(k);
    }
};
Back to top page