-
Notifications
You must be signed in to change notification settings - Fork 153
/
binary_indexed_tree_range_query_range_update.cpp
88 lines (79 loc) · 1.96 KB
/
binary_indexed_tree_range_query_range_update.cpp
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
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MOD = 1000000000+7;
const int INF = 1000000000+5;
/**
* Description: BIT RURQ (Support range queries and range updates of 1-D array)
* Usage: query O(lg(N)), update O(lg(N))
* Source: https://github.com/dragonslayerx
* Note: Use 1-based indexing
*/
// Remember to use 1 based indexing
class BIT {
static const int MAX = 100005;
public:
static long long query(long long *bit, int indx)
{
long long sum = 0;
while (indx) {
sum += bit[indx];
indx -= (indx & -indx);
}
return sum;
}
static void update(long long *bit, int indx, long long x)
{
while (indx < MAX) {
bit[indx] += x;
indx += (indx & -indx);
}
}
};
class BitRPRQ {
static const int MAX = 100005;
long long B1[MAX];
long long B2[MAX];
public:
BitRPRQ() {
memset(B1, 0, sizeof(B1));
memset(B2, 0, sizeof(B2));
}
long long Rquery(int p){
long long tempB1 = BIT::query(B1, p);
long long tempB2 = BIT::query(B2, p);
long long sum = tempB1 * p + tempB2;
return sum;
}
long long Rupdate(int l, int r, long long v){
BIT::update(B1, l, v);
BIT::update(B1, r+1, -v);
BIT::update(B2, l, -((l-1)*v));
BIT::update(B2, r+1, r*v);
}
};
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n, q;
scanf("%d%d", &n, &q);
BitRPRQ B;
while (q--) {
int choice;
scanf("%d", &choice);
int p, q;
long long v;
scanf("%d%d", &p, &q);
if (choice==0) {
long long v;
scanf("%lld", &v);
B.Rupdate(p, q, v);
} else {
long long Answer = B.Rquery(q)-B.Rquery(p-1);
printf("%lld\n", Answer);
}
}
}
}