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
| /**
* https://www.luogu.com.cn/problem/P3372
*/
#include<bits/stdc++.h>
using namespace std;
int n, m;
long long a[100010], f[400010], ex[400010];
inline void BuildTree(int k, int l, int r) {
ex[k] = 0;
if (l == r) {
f[k] = a[l];
return;
}
int m = (l + r) >> 1;
BuildTree(k + k, l, m);
BuildTree(k + k + 1, m+1, r);
f[k] = f[k + k] + f[k + k + 1];
return;
}
/* 单点修改 */
inline void add(int k, int l, int r, int p, int v) {
f[k] += v;
if (l == r) return;
int m = (l + r) >> 1;
if (p <= m)
add(k+k,l,m,p,v);
else
add(k+k+1,m+1,r,p,v);
}
/* 区间修改 */
inline void add2(int k, int l ,int r, int h, int t, int v) {
if (l == h && r == t) {
ex[k] += v;
return;
}
f[k] += (t-h+1) * v;
int m = (l + r) >> 1;
if (t <= m)
add2(k+k,l,m,h,t,v);
else if (h > m)
add2(k+k+1,m+1,r,h,t,v);
else {
add2(k+k,l,m,h,m,v);
add2(k+k+1,m+1,r,m+1,t,v);
}
}
inline long long query(int k, int l, int r, int h, int t) {
if (l == h && r == t) return f[k];
int m = (l + r) >> 1;
if (t <= m)
return query(k+k,l,m,h,t);
else if (h > m)
return query(k+k+1,m+1,r,h,t);
else return query(k+k,l,m,h,m) + query(k+k+1,m+1,r,m+1,t);
}
inline long long query2(int k, int l, int r, int h, int t, long long p) {
p += ex[k];
if (l == h && r == t) return f[k] + p * (r - l + 1);
int m = (l + r) >> 1;
if (t <= m)
return query2(k+k,l,m,h,t,p);
else if (h > m)
return query2(k+k+1,m+1,r,h,t,p);
else return query2(k+k,l,m,h,m,p) + query2(k+k+1,m+1,r,m+1,t,p);
}
int main() {
scanf("%d%d",&n,&m);
for (int i = 1; i <= n; ++i)
scanf("%lld",&a[i]);
BuildTree(1,1,n);
for (int i = 1; i <= m; ++i) {
int op;
scanf("%d",&op);
if (op == 1) {
int x, y, v;
scanf("%d%d%d",&x,&y,&v);
add2(1,1,n,x,y,v);
} else {
int x, y;
scanf("%d%d",&x,&y);
printf("%lld\n", query2(1,1,n,x,y,0));
}
}
return 0;
}
|