-
Notifications
You must be signed in to change notification settings - Fork 174
/
Copy pathRange Updates and Sums.cpp
108 lines (91 loc) · 1.98 KB
/
Range Updates and Sums.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxN = 2e5;
int N, Q, t, a, b, lo[4*maxN], hi[4*maxN];
ll x, del[4*maxN], ass[4*maxN], sum[4*maxN];
int len(int i){
return hi[i]-lo[i]+1;
}
void increment(int i, ll v){
del[i] += v;
sum[i] += len(i) * v;
}
void assign(int i, ll v){
ass[i] = v;
del[i] = 0;
sum[i] = len(i) * v;
}
void push(int i){
if(ass[i]){
assign(2*i, ass[i]);
assign(2*i+1, ass[i]);
ass[i] = 0;
}
if(del[i]){
increment(2*i, del[i]);
increment(2*i+1, del[i]);
del[i] = 0;
}
}
void pull(int i){
sum[i] = sum[2*i] + sum[2*i+1];
}
void build(int i, int l, int r){
lo[i] = l; hi[i] = r;
if(l == r){
scanf("%lld", &sum[i]);
return;
}
int m = l+(r-l)/2;
build(2*i, l, m);
build(2*i+1, m+1, r);
pull(i);
}
void increment(int i, int l, int r, ll v){
if(l > hi[i] || r < lo[i]) return;
if(l <= lo[i] && hi[i] <= r){
increment(i, v); return;
}
push(i);
increment(2*i, l, r, v);
increment(2*i+1, l, r, v);
pull(i);
}
void assign(int i, int l, int r, ll v){
if(l > hi[i] || r < lo[i]) return;
if(l <= lo[i] && hi[i] <= r){
assign(i, v); return;
}
push(i);
assign(2*i, l, r, v);
assign(2*i+1, l, r, v);
pull(i);
}
ll query(int i, int l, int r){
if(l > hi[i] || r < lo[i]) return 0;
if(l <= lo[i] && hi[i] <= r){
return sum[i];
}
push(i);
ll lsum = query(2*i, l, r);
ll rsum = query(2*i+1, l, r);
pull(i);
return lsum + rsum;
}
int main(){
scanf("%d %d", &N, &Q);
build(1, 1, N);
for(int q = 0; q < Q; q++){
scanf("%d %d %d", &t, &a, &b);
if(t == 1){
scanf("%lld", &x);
increment(1, a, b, x);
} else if(t == 2){
scanf("%lld", &x);
assign(1, a, b, x);
} else if(t == 3){
printf("%lld\n", query(1, a, b));
}
}
}