-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBIT.cpp
More file actions
99 lines (83 loc) · 1.98 KB
/
BIT.cpp
File metadata and controls
99 lines (83 loc) · 1.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
template<typename T>
class BIT
{
private:
const int tree_size;
const function<T(T,T)> op;
const T e;
const function<T(T)> inv;
vector<T> node;
const int least_square(const int k) const
{
int tmp=k;
for(int i=1; 64>i; i<<=1)
tmp |= (tmp >> i);
return tmp+1;
}
public:
const int SIZE;
BIT(const vector<T> &ary, const function<T(T,T)> f, const T e_, const function<T(T)> inv_);
const void add(const int k, const T x);
const T fold(const int k) const;
const T fold(const int a,const int b) const
{
return op(fold(b), inv(a==0?e:fold(a-1)));
}
const void print() const
{
REP(i, tree_size)
cout<<node[i]<<" \n"[i==tree_size-1];
}
};
template<typename T>
BIT<T>::BIT(const vector<T> &ary, const function<T(T,T)> f, const T e_, const function<T(T)> inv_)
:tree_size(least_square(ary.size()+1)),op(f),e(e_),inv(inv_),SIZE(ary.size())
{
node=vector<T>(tree_size, e);
for(int i=1;i<=SIZE;i++)
add(i, ary[i-1]);
}
template<typename T>
const void BIT<T>::add(const int k, const T x) //k...0 origin
{
for(int j=k+1;j<=tree_size;j+=(j&-j))
node[j]=op(node[j], x);
}
template<typename T>
const T BIT<T>::fold(const int k) const
{
T tmp=e;
for(int j=k+1;j>0;j=j&(j-1))
tmp=op(tmp, node[j]);
return tmp;
}
#define PLUS [](int p,int q){return p+q;},0,[](int x){return -x;}
template<typename T>
class RARS
{
public:
BIT<T> bit0, bit1;
RARS(const vector<T> &ary, const function<T(T,T)> f, const T e_, const function<T(T)> inv_)
:bit0(ary, f, e_, inv_), bit1(vector<T>(ary.size()), f, e_, inv_)
{}
const void add(const int l, const int r, const int x)
{
bit0.add(l, -x*l);
bit1.add(l,x);
bit0.add(r,x*r);
bit1.add(r,-x);
}
const T sum(const int k) const
{
return bit0.fold(k)+bit1.fold(k)*k;
}
const T get(const int k) const
{
return sum(k+1)-sum(k);
}
const void print() const
{
REP(i, bit0.SIZE)
cout<<get(i)<<" \n"[i==bit0.SIZE-1];
}
};