1
+ // A Fenwick BIT or binary indexed tree is a data structure providing efficient methods
2
+ // for calculation and manipulation of the prefix sums of a table of values.
3
+
4
+ // 1D version
5
+ // 空间复杂度O(n), 初始化时间复杂度O(n*log n), 查询区间复杂度O(log n)
6
+ // n —— maximum value which will have non-zero frequency
7
+ // idx is some index of BIT. r is a position in idx of the last digit 1 (from left to right) in binary notation.
8
+ // BIT[idx] is sum of frequencies from index (idx - 2^r + 1) to index idx.
9
+ // We also write that idx is responsible for indexes from (idx - 2^r + 1) to idx.
10
+
11
+ // Sample C Implementation
12
+
13
+ int lowbit (int x)
14
+ {
15
+ return x & (-x);
16
+ }
17
+
18
+ void update (int i, int delta)
19
+ {
20
+ while (i <= MaxVal)// MaxVal —— maximum value which will have non-zero frequency
21
+ {
22
+ BIT[i] += delta;
23
+ i += lowbit (i);
24
+ }
25
+ return ;
26
+ }
27
+
28
+ int query (int k)
29
+ {
30
+ int ans = 0 ;
31
+ while (k > 0 )
32
+ {
33
+ ans += BIT[k];
34
+ k -= lowbit (k);
35
+ }
36
+ return ans;
37
+ }
38
+
39
+ // the actual frequency at a position idx can be calculated by calling function qeury twice
40
+ // f[idx] = query(idx) - query(idx - 1), but the function below is faster
41
+ int querySingle (int idx)
42
+ {
43
+ int sum = BIT[idx]; // sum will be decreased
44
+ if (idx > 0 )
45
+ { // special case
46
+ int z = idx - lowbit (idx); // make z first
47
+ --idx; // idx is no important any more, so instead y, you can use idx
48
+ while (idx != z)
49
+ { // at some iteration idx (y) will become z
50
+ sum -= BIT[idx];
51
+ // substruct BIT frequency which is between y and "the same path"
52
+ idx -= lowbit (idx);
53
+ }
54
+ }
55
+ return sum;
56
+ }
57
+
58
+ // Scaling the entire BIT by a constant factor c
59
+ void scale (int c)// c is maybe not an integer
60
+ {
61
+ void scale (int c)
62
+ {
63
+ for (int i = 1 ; i <= MaxVal; i++)
64
+ BIT[i] *= c;
65
+ // here we assume that c is used to multiply the original frenquency(maybe divide)
66
+ }
67
+ return ;
68
+ }
69
+
70
+ // Find index with given cumulative frequency
71
+
72
+ // if in BIT exists more than one index with a same
73
+ // cumulative frequency, this procedure will return
74
+ // some of them (we do not know which one)
75
+
76
+ // bitMask - initialy, it is the greatest bit of MaxVal
77
+ // bitMask store interval which should be searched
78
+ int find (int cumFre)
79
+ {
80
+ int idx = 0 ; // this var is result of function
81
+
82
+ while ((bitMask != 0 ) && (idx < MaxVal))
83
+ { // nobody likes overflow :)
84
+ int tIdx = idx + bitMask; // we make midpoint of interval
85
+ if (cumFre == BIT[tIdx]) // if it is equal, we just return idx
86
+ return tIdx;
87
+ else if (cumFre > BIT[tIdx])
88
+ { // if BIT frequency "can fit" into cumFre, then include it
89
+ idx = tIdx; // update index
90
+ cumFre -= BIT[tIdx]; // set frequency for next loop
91
+ }
92
+ bitMask >>= 1 ; // half current interval
93
+ }
94
+ if (cumFre != 0 ) // maybe given cumulative frequency doesn't exist
95
+ return -1 ;
96
+ else
97
+ return idx;
98
+ }
99
+ // if in BIT exists more than one index with a same
100
+ // cumulative frequency, this procedure will return
101
+ // the greatest one
102
+ int findG (int cumFre){
103
+ int idx = 0 ;
104
+
105
+ while ((bitMask != 0 ) && (idx < MaxVal)){
106
+ int tIdx = idx + bitMask;
107
+ if (cumFre >= BIT[tIdx])
108
+ {// if current cumulative frequency is equal to cumFre,
109
+ // we are still looking for higher index (if exists)
110
+ idx = tIdx;
111
+ cumFre -= BIT[tIdx];
112
+ }
113
+ bitMask >>= 1 ;
114
+ }
115
+ if (cumFre != 0 )
116
+ return -1 ;
117
+ else
118
+ return idx;
119
+ }
120
+ // Time complexity: O(log MaxVal)
121
+
122
+ // Sample C++ Implementation(a bit different idea)
123
+
124
+ class Fenwick_BIT_Sum
125
+ {
126
+ vector< int > BIT;
127
+ Fenwick_BIT_Sum (const vector< int >& Arg)// Arg is our array on which we are going to work
128
+ {
129
+ BIT.resize (Arg.size ());
130
+ for (int i = 0 ; i < BIT.size (); ++i)
131
+ increase (i, Arg[i]);
132
+ }
133
+
134
+ // Increases value of i-th element by ''delta''.
135
+ void increase (int i, int delta)
136
+ {
137
+ for (; i < (int )BIT.size (); i |= i + 1 )
138
+ BIT[i] += delta;
139
+ }
140
+
141
+ // Returns sum of elements with indexes left..right, inclusive; (zero-based);
142
+ int getsum (int left, int right)
143
+ {
144
+ return sum (right) - sum (left - 1 ); // when left equals 0 the function hopefully returns 0
145
+ }
146
+
147
+ int sum (int ind)
148
+ {
149
+ int sum = 0 ;
150
+ while (ind >= 0 )
151
+ {
152
+ sum += BIT[ind];
153
+ ind &= ind + 1 ;
154
+ --ind;
155
+ }
156
+ return sum;
157
+ }
158
+ };
159
+
160
+ // 2D version
161
+
162
+ int lowbit (int t)
163
+ {
164
+ return t & (-t);
165
+ }
166
+
167
+ void update (int i, int j, int delta)
168
+ {
169
+ A[i][j] += delta;
170
+ for (int x = i; x <= MaxVal_X; x += lowbit (x))
171
+ for (int y = j; y <= MaxVal_Y; y += lowbit (y))
172
+ BIT[x][y] += delta;
173
+ return ;
174
+ }
175
+
176
+ int query (int i, int j)
177
+ {
178
+ int result = 0 ;
179
+ for (int x = i; x > 0 ; x -= lowbit (x))
180
+ for (int y = j; y > 0 ; y -= lowbit (y))
181
+ result += BIT[x][y];
182
+ return result;
183
+ }
184
+
185
+ // 多维树状数组与一维二维树状数组实现很相似,只是在查询区间时注意容斥原理的使用
0 commit comments