ecnerwala's competitive programming library
#include "bit.hpp"
| Coverage | Exec / Excl / Total | |
|---|---|---|
| Lines | 0.0% | 0 / 0 / 57 |
| Full report |
#pragma once
#include <vector>
#include <cassert>
/** Binary-indexed tree
*
* A binary indexed tree with N nodes of type T provides the
* following two functions for 0 <= i <= N:
*
* prefix(int i) -> prefix_iterator<T>
* suffix(int i) -> suffix_iterator<T>
*
* such that size(suffix(i) intersect prefix(j)) = (1 if i < j else 0).
* Furthermore, the resulting lists always have size at most log_2(N).
*
* This can be used to implement either point-update/(prefix|suffix)-query or
* (prefix|suffix)-update/point-query over a virtual array of size N of a
* commutative monoid. This can be generalized to implement
* point-update/range-query or range-update/point-query over a virtual array
* of size N of a commutative group.
*
* With 0-indexed data, prefixes are more natural:
* * For range update/query, use for_prefix for the ranges and for_suffix for the points.
* * For prefix update/query, no change.
* * For suffix update/query, use for_prefix(point + 1); 1-index the data.
*/
template <typename T> class binary_indexed_tree {
private:
std::vector<T> dat;
public:
binary_indexed_tree() {}
explicit binary_indexed_tree(size_t N) : dat(N) {}
binary_indexed_tree(size_t N, const T& t) : dat(N, t) {}
size_t size() const { return dat.size(); }
const std::vector<T>& data() const { return dat; }
std::vector<T>& data() { return dat; }
private:
template <typename I, typename S = I> struct iterator_range {
private:
I begin_;
S end_;
public:
iterator_range() : begin_(), end_() {}
iterator_range(const I& begin__, const S& end__) : begin_(begin__), end_(end__) {}
iterator_range(I&& begin__, S&& end__) : begin_(begin__), end_(end__) {}
I begin() const { return begin_; }
S end() const { return end_; }
};
public:
class const_suffix_iterator {
private:
const T* dat;
int a;
const_suffix_iterator(const T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const const_suffix_iterator& i, const const_suffix_iterator& j) {
assert(j.dat == nullptr);
return i.a < j.a;
}
const_suffix_iterator& operator ++ () {
a |= a+1;
return *this;
}
const T& operator * () const {
return dat[a];
}
};
using const_suffix_range = iterator_range<const_suffix_iterator>;
const_suffix_range suffix(int a) const {
assert(0 <= a && a <= int(dat.size()));
return const_suffix_range{const_suffix_iterator{dat.data(), a}, const_suffix_iterator{nullptr, int(dat.size())}};
}
class suffix_iterator {
private:
T* dat;
int a;
suffix_iterator(T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const suffix_iterator& i, const suffix_iterator& j) {
assert(j.dat == nullptr);
return i.a < j.a;
}
suffix_iterator& operator ++ () {
a |= a+1;
return *this;
}
T& operator * () const {
return dat[a];
}
};
using suffix_range = iterator_range<suffix_iterator>;
suffix_range suffix(int a) {
assert(0 <= a && a <= int(dat.size()));
return suffix_range{suffix_iterator{dat.data(), a}, suffix_iterator{nullptr, int(dat.size())}};
}
class const_prefix_iterator {
private:
const T* dat;
int a;
const_prefix_iterator(const T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const const_prefix_iterator& i, const const_prefix_iterator& j) {
assert(j.dat == nullptr);
return i.a > 0;
}
const_prefix_iterator& operator ++ () {
a &= a-1;
return *this;
}
const T& operator * () const {
return dat[a-1];
}
};
using const_prefix_range = iterator_range<const_prefix_iterator>;
const_prefix_range prefix(int a) const {
return const_prefix_range{const_prefix_iterator{dat.data(), a}, const_prefix_iterator{nullptr, 0}};
}
class prefix_iterator {
private:
T* dat;
int a;
prefix_iterator(T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const prefix_iterator& i, const prefix_iterator& j) {
assert(j.dat == nullptr);
return i.a > 0;
}
prefix_iterator& operator ++ () {
a &= a-1;
return *this;
}
T& operator * () const {
return dat[a-1];
}
};
using prefix_range = iterator_range<prefix_iterator>;
prefix_range prefix(int a) {
return prefix_range{prefix_iterator{dat.data(), a}, prefix_iterator{nullptr, 0}};
}
};
#include <vector>
#include <cassert>
#line 2 "src/bit.hpp"
#line 5 "src/bit.hpp"
/** Binary-indexed tree
*
* A binary indexed tree with N nodes of type T provides the
* following two functions for 0 <= i <= N:
*
* prefix(int i) -> prefix_iterator<T>
* suffix(int i) -> suffix_iterator<T>
*
* such that size(suffix(i) intersect prefix(j)) = (1 if i < j else 0).
* Furthermore, the resulting lists always have size at most log_2(N).
*
* This can be used to implement either point-update/(prefix|suffix)-query or
* (prefix|suffix)-update/point-query over a virtual array of size N of a
* commutative monoid. This can be generalized to implement
* point-update/range-query or range-update/point-query over a virtual array
* of size N of a commutative group.
*
* With 0-indexed data, prefixes are more natural:
* * For range update/query, use for_prefix for the ranges and for_suffix for the points.
* * For prefix update/query, no change.
* * For suffix update/query, use for_prefix(point + 1); 1-index the data.
*/
template <typename T> class binary_indexed_tree {
private:
std::vector<T> dat;
public:
binary_indexed_tree() {}
explicit binary_indexed_tree(size_t N) : dat(N) {}
binary_indexed_tree(size_t N, const T& t) : dat(N, t) {}
size_t size() const { return dat.size(); }
const std::vector<T>& data() const { return dat; }
std::vector<T>& data() { return dat; }
private:
template <typename I, typename S = I> struct iterator_range {
private:
I begin_;
S end_;
public:
iterator_range() : begin_(), end_() {}
iterator_range(const I& begin__, const S& end__) : begin_(begin__), end_(end__) {}
iterator_range(I&& begin__, S&& end__) : begin_(begin__), end_(end__) {}
I begin() const { return begin_; }
S end() const { return end_; }
};
public:
class const_suffix_iterator {
private:
const T* dat;
int a;
const_suffix_iterator(const T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const const_suffix_iterator& i, const const_suffix_iterator& j) {
assert(j.dat == nullptr);
return i.a < j.a;
}
const_suffix_iterator& operator ++ () {
a |= a+1;
return *this;
}
const T& operator * () const {
return dat[a];
}
};
using const_suffix_range = iterator_range<const_suffix_iterator>;
const_suffix_range suffix(int a) const {
assert(0 <= a && a <= int(dat.size()));
return const_suffix_range{const_suffix_iterator{dat.data(), a}, const_suffix_iterator{nullptr, int(dat.size())}};
}
class suffix_iterator {
private:
T* dat;
int a;
suffix_iterator(T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const suffix_iterator& i, const suffix_iterator& j) {
assert(j.dat == nullptr);
return i.a < j.a;
}
suffix_iterator& operator ++ () {
a |= a+1;
return *this;
}
T& operator * () const {
return dat[a];
}
};
using suffix_range = iterator_range<suffix_iterator>;
suffix_range suffix(int a) {
assert(0 <= a && a <= int(dat.size()));
return suffix_range{suffix_iterator{dat.data(), a}, suffix_iterator{nullptr, int(dat.size())}};
}
class const_prefix_iterator {
private:
const T* dat;
int a;
const_prefix_iterator(const T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const const_prefix_iterator& i, const const_prefix_iterator& j) {
assert(j.dat == nullptr);
return i.a > 0;
}
const_prefix_iterator& operator ++ () {
a &= a-1;
return *this;
}
const T& operator * () const {
return dat[a-1];
}
};
using const_prefix_range = iterator_range<const_prefix_iterator>;
const_prefix_range prefix(int a) const {
return const_prefix_range{const_prefix_iterator{dat.data(), a}, const_prefix_iterator{nullptr, 0}};
}
class prefix_iterator {
private:
T* dat;
int a;
prefix_iterator(T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const prefix_iterator& i, const prefix_iterator& j) {
assert(j.dat == nullptr);
return i.a > 0;
}
prefix_iterator& operator ++ () {
a &= a-1;
return *this;
}
T& operator * () const {
return dat[a-1];
}
};
using prefix_range = iterator_range<prefix_iterator>;
prefix_range prefix(int a) {
return prefix_range{prefix_iterator{dat.data(), a}, prefix_iterator{nullptr, 0}};
}
};
// clang-format off
// @formatter:off
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
#pragma GCC diagnostic ignored "-Wmultistatement-macros"
#include <bits/stdc++.h>
#include <cassert>
// src/bit.hpp
template<typename T>class binary_indexed_tree{
private:
std::vector<T>dat;
public:
binary_indexed_tree(){}
explicit binary_indexed_tree(size_t N):dat(N){}
binary_indexed_tree(size_t N,const T&t):dat(N,t){}
size_t size()const{return dat.size();}
const std::vector<T>&data()const{return dat;}
std::vector<T>&data(){return dat;}
private:
template<typename I,typename S=I>struct iterator_range{
private:
I begin_;
S end_;
public:
iterator_range():begin_(),end_(){}
iterator_range(const I&begin__,const S&end__):begin_(begin__),end_(end__){}
iterator_range(I&&begin__,S&&end__):begin_(begin__),end_(end__){}
I begin()const{return begin_;}
S end()const{return end_;}
};
public:
class const_suffix_iterator{
private:
const T*dat;
int a;
const_suffix_iterator(const T*dat_,int a_):dat(dat_),a(a_){}
friend class binary_indexed_tree;
public:
friend bool operator!=(const const_suffix_iterator&i,const const_suffix_iterator&j){
assert(j.dat==nullptr);
return i.a<j.a;
}
const_suffix_iterator&operator++(){
a|=a+1;
return*this;
}
const T&operator*()const{
return dat[a];
}
};
using const_suffix_range=iterator_range<const_suffix_iterator>;
const_suffix_range suffix(int a)const{
assert(0<=a&&a<=int(dat.size()));
return const_suffix_range{const_suffix_iterator{dat.data(),a},const_suffix_iterator{nullptr,int(dat.size())}};
}
class suffix_iterator{
private:
T*dat;
int a;
suffix_iterator(T*dat_,int a_):dat(dat_),a(a_){}
friend class binary_indexed_tree;
public:
friend bool operator!=(const suffix_iterator&i,const suffix_iterator&j){
assert(j.dat==nullptr);
return i.a<j.a;
}
suffix_iterator&operator++(){
a|=a+1;
return*this;
}
T&operator*()const{
return dat[a];
}
};
using suffix_range=iterator_range<suffix_iterator>;
suffix_range suffix(int a){
assert(0<=a&&a<=int(dat.size()));
return suffix_range{suffix_iterator{dat.data(),a},suffix_iterator{nullptr,int(dat.size())}};
}
class const_prefix_iterator{
private:
const T*dat;
int a;
const_prefix_iterator(const T*dat_,int a_):dat(dat_),a(a_){}
friend class binary_indexed_tree;
public:
friend bool operator!=(const const_prefix_iterator&i,const const_prefix_iterator&j){
assert(j.dat==nullptr);
return i.a>0;
}
const_prefix_iterator&operator++(){
a&=a-1;
return*this;
}
const T&operator*()const{
return dat[a-1];
}
};
using const_prefix_range=iterator_range<const_prefix_iterator>;
const_prefix_range prefix(int a)const{
return const_prefix_range{const_prefix_iterator{dat.data(),a},const_prefix_iterator{nullptr,0}};
}
class prefix_iterator{
private:
T*dat;
int a;
prefix_iterator(T*dat_,int a_):dat(dat_),a(a_){}
friend class binary_indexed_tree;
public:
friend bool operator!=(const prefix_iterator&i,const prefix_iterator&j){
assert(j.dat==nullptr);
return i.a>0;
}
prefix_iterator&operator++(){
a&=a-1;
return*this;
}
T&operator*()const{
return dat[a-1];
}
};
using prefix_range=iterator_range<prefix_iterator>;
prefix_range prefix(int a){
return prefix_range{prefix_iterator{dat.data(),a},prefix_iterator{nullptr,0}};
}
};
#pragma GCC diagnostic pop
// clang-format on
// @formatter:on
#pragma once
#include <vector>
#include <cassert>
/** Binary-indexed tree
*
* A binary indexed tree with N nodes of type T provides the
* following two functions for 0 <= i <= N:
*
* prefix(int i) -> prefix_iterator<T>
* suffix(int i) -> suffix_iterator<T>
*
* such that size(suffix(i) intersect prefix(j)) = (1 if i < j else 0).
* Furthermore, the resulting lists always have size at most log_2(N).
*
* This can be used to implement either point-update/(prefix|suffix)-query or
* (prefix|suffix)-update/point-query over a virtual array of size N of a
* commutative monoid. This can be generalized to implement
* point-update/range-query or range-update/point-query over a virtual array
* of size N of a commutative group.
*
* With 0-indexed data, prefixes are more natural:
* * For range update/query, use for_prefix for the ranges and for_suffix for the points.
* * For prefix update/query, no change.
* * For suffix update/query, use for_prefix(point + 1); 1-index the data.
*/
template <typename T> class binary_indexed_tree {
private:
std::vector<T> dat;
public:
binary_indexed_tree() {}
explicit binary_indexed_tree(size_t N) : dat(N) {}
binary_indexed_tree(size_t N, const T& t) : dat(N, t) {}
size_t size() const { return dat.size(); }
const std::vector<T>& data() const { return dat; }
std::vector<T>& data() { return dat; }
private:
template <typename I, typename S = I> struct iterator_range {
private:
I begin_;
S end_;
public:
iterator_range() : begin_(), end_() {}
iterator_range(const I& begin__, const S& end__) : begin_(begin__), end_(end__) {}
iterator_range(I&& begin__, S&& end__) : begin_(begin__), end_(end__) {}
I begin() const { return begin_; }
S end() const { return end_; }
};
public:
class const_suffix_iterator {
private:
const T* dat;
int a;
const_suffix_iterator(const T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const const_suffix_iterator& i, const const_suffix_iterator& j) {
assert(j.dat == nullptr);
return i.a < j.a;
}
const_suffix_iterator& operator ++ () {
a |= a+1;
return *this;
}
const T& operator * () const {
return dat[a];
}
};
using const_suffix_range = iterator_range<const_suffix_iterator>;
const_suffix_range suffix(int a) const {
assert(0 <= a && a <= int(dat.size()));
return const_suffix_range{const_suffix_iterator{dat.data(), a}, const_suffix_iterator{nullptr, int(dat.size())}};
}
class suffix_iterator {
private:
T* dat;
int a;
suffix_iterator(T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const suffix_iterator& i, const suffix_iterator& j) {
assert(j.dat == nullptr);
return i.a < j.a;
}
suffix_iterator& operator ++ () {
a |= a+1;
return *this;
}
T& operator * () const {
return dat[a];
}
};
using suffix_range = iterator_range<suffix_iterator>;
suffix_range suffix(int a) {
assert(0 <= a && a <= int(dat.size()));
return suffix_range{suffix_iterator{dat.data(), a}, suffix_iterator{nullptr, int(dat.size())}};
}
class const_prefix_iterator {
private:
const T* dat;
int a;
const_prefix_iterator(const T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const const_prefix_iterator& i, const const_prefix_iterator& j) {
assert(j.dat == nullptr);
return i.a > 0;
}
const_prefix_iterator& operator ++ () {
a &= a-1;
return *this;
}
const T& operator * () const {
return dat[a-1];
}
};
using const_prefix_range = iterator_range<const_prefix_iterator>;
const_prefix_range prefix(int a) const {
return const_prefix_range{const_prefix_iterator{dat.data(), a}, const_prefix_iterator{nullptr, 0}};
}
class prefix_iterator {
private:
T* dat;
int a;
prefix_iterator(T* dat_, int a_) : dat(dat_), a(a_) {}
friend class binary_indexed_tree;
public:
friend bool operator != (const prefix_iterator& i, const prefix_iterator& j) {
assert(j.dat == nullptr);
return i.a > 0;
}
prefix_iterator& operator ++ () {
a &= a-1;
return *this;
}
T& operator * () const {
return dat[a-1];
}
};
using prefix_range = iterator_range<prefix_iterator>;
prefix_range prefix(int a) {
return prefix_range{prefix_iterator{dat.data(), a}, prefix_iterator{nullptr, 0}};
}
};