Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
segtree_dual.hpp
[詳解]
1#pragma once
2#include"../../kyopro_library/template.hpp"
3
4/// @brief 双対セグメント木
5/// @tparam CommutativeOperator 作用素
6/// @attention 作用素は果敢である必要がある
7template<typename CommutativeOperator>
8struct SegTreeDual {
9 using Type=typename CommutativeOperator::Type;
10 SegTreeDual()=default;
11
12 /// @brief 要素数 n の双対セグ木を構築する
13 SegTreeDual(int n) {
14 this->n=n;
15 dat.assign(n<<1,CommutativeOperator::id());
16 }
17
18 /// @brief 配列 v から双対セグ木を構築する
19 SegTreeDual(const vector<Type>& v) {
20 this->n=v.size();
21 dat.assign(n<<1,CommutativeOperator::id());
22 for(int i=0; i<n; i++) dat[i+n]=v[i];
23 for(int i=n-1; i>0; i--) dat[i]=CommutativeOperator::op(dat[i<<1],dat[i<<1|1]);
24 }
25
26 void apply(int l, int r, Type x) {
27 l+=n,r+=n;
28 while(l<r) {
29 if(l&1) dat[l]=CommutativeOperator::op(dat[l],x),l++;
30 if(r&1) r--,dat[r]=CommutativeOperator::op(dat[r],x);
31 l>>=1,r>>=1;
32 }
33 }
34 Type get(int i) {
35 i+=n;
36 Type ret=CommutativeOperator::id();
37 while(i) {
38 ret=CommutativeOperator::op(ret,dat[i]);
39 i>>=1;
40 }
41 return ret;
42 }
43
44 int size() { return n; }
45 Type operator[](int i) { return get(i); }
46
47private:
48 int n;
49 vector<Type> dat;
50};
51
52#include"../../kyopro_library/others/operator.hpp"
53
54namespace RangeQuery {
55 template<typename T>
56 struct ApplyAdd { using Type=struct SegTreeDual<Operator::Add<T>>; };
57
58 template<typename T>
59 struct ApplyUpdate { using Type=struct SegTreeDual<Operator::UpdateTimeStamp<T>>; };
60}
作用素
Definition operator.hpp:5
区間クエリ
Definition segtree.hpp:136
可換な更新(タイムスタンプ)
Definition operator.hpp:24
双対セグメント木
SegTreeDual(int n)
要素数 n の双対セグ木を構築する
void apply(int l, int r, Type x)
SegTreeDual(const vector< Type > &v)
配列 v から双対セグ木を構築する
Type get(int i)
Type operator[](int i)
SegTreeDual()=default