Library

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

View the Project on GitHub ebi-fly13/Library

:heavy_check_mark: Sparse Table
(data_structure/sparse_table.hpp)

説明

静的配列のmin, max, gcdなどの区間クエリを処理することができる。構築 $O(N\log N)$、クエリ $O(1)$

Required by

Verified with

Code

#pragma once

#include <vector>


/*
    reference: https://scrapbox.io/data-structures/Sparse_Table
*/

namespace ebi {

template <class Band, Band (*op)(Band, Band)> struct sparse_table {
  public:
    sparse_table() = default;

    sparse_table(const std::vector<Band> &a) : n(a.size()) {
        table = std::vector(std::__lg(n) + 1, std::vector<Band>(n));
        for (int i = 0; i < n; i++) {
            table[0][i] = a[i];
        }
        for (int k = 1; (1 << k) <= n; k++) {
            for (int i = 0; i + (1 << k) <= n; i++) {
                table[k][i] =
                    op(table[k - 1][i], table[k - 1][i + (1 << (k - 1))]);
            }
        }
    }

    void build(const std::vector<Band> &a) {
        n = (int)a.size();
        table = std::vector(std::__lg(n) + 1, std::vector<Band>(n));
        for (int i = 0; i < n; i++) {
            table[0][i] = a[i];
        }
        for (int k = 1; (1 << k) <= n; k++) {
            for (int i = 0; i + (1 << k) <= n; i++) {
                table[k][i] =
                    op(table[k - 1][i], table[k - 1][i + (1 << (k - 1))]);
            }
        }
    }

    // [l, r)

    Band fold(int l, int r) {
        int k = std::__lg(r - l);
        return op(table[k][l], table[k][r - (1 << k)]);
    }

  private:
    int n;
    std::vector<std::vector<Band>> table;
};

}  // namespace ebi
#line 2 "data_structure/sparse_table.hpp"

#include <vector>


/*
    reference: https://scrapbox.io/data-structures/Sparse_Table
*/

namespace ebi {

template <class Band, Band (*op)(Band, Band)> struct sparse_table {
  public:
    sparse_table() = default;

    sparse_table(const std::vector<Band> &a) : n(a.size()) {
        table = std::vector(std::__lg(n) + 1, std::vector<Band>(n));
        for (int i = 0; i < n; i++) {
            table[0][i] = a[i];
        }
        for (int k = 1; (1 << k) <= n; k++) {
            for (int i = 0; i + (1 << k) <= n; i++) {
                table[k][i] =
                    op(table[k - 1][i], table[k - 1][i + (1 << (k - 1))]);
            }
        }
    }

    void build(const std::vector<Band> &a) {
        n = (int)a.size();
        table = std::vector(std::__lg(n) + 1, std::vector<Band>(n));
        for (int i = 0; i < n; i++) {
            table[0][i] = a[i];
        }
        for (int k = 1; (1 << k) <= n; k++) {
            for (int i = 0; i + (1 << k) <= n; i++) {
                table[k][i] =
                    op(table[k - 1][i], table[k - 1][i + (1 << (k - 1))]);
            }
        }
    }

    // [l, r)

    Band fold(int l, int r) {
        int k = std::__lg(r - l);
        return op(table[k][l], table[k][r - (1 << k)]);
    }

  private:
    int n;
    std::vector<std::vector<Band>> table;
};

}  // namespace ebi
Back to top page