题目
题目传送门
给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:
1、“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d。
2、“Q l r”,表示询问 数列中第 l~r 个数的和。
对于每个询问,输出一个整数表示答案。
输入格式
第一行两个整数N,M。
第二行N个整数A[i]。
接下来M行表示M条指令,每条指令的格式如题目描述所示。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
样例输入
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
样例输出
4
55
9
15
题解
∑
i
=
1
x
b
[
i
]
\sum\limits_{i=1}^{x}b{[i]}
i=1∑xb[i]就是
a
[
i
]
a[i]
a[i]增加的值
那么
a
[
1
∼
x
]
a[1 \sim x]
a[1∼x]整体增加的值就是
∑
i
=
1
x
∑
j
=
1
i
b
[
j
]
\sum\limits_{i=1}^{x}\sum\limits_{j=1}^{i}b[j]
i=1∑xj=1∑ib[j]
上式可以改写为
∑
i
=
1
x
∑
j
=
1
i
b
[
j
]
=
∑
i
=
1
x
(
x
−
i
+
1
)
∗
b
[
i
]
=
(
x
+
1
)
∑
i
=
1
x
b
[
i
]
−
∑
i
x
i
∗
b
[
i
]
\sum\limits_{i=1}^{x}\sum\limits_{j=1}^{i}b[j] =\sum\limits_{i=1}^{x}(x-i+1)*b[i]=(x+1)\sum\limits_{i=1}^{x}b[i]-\sum\limits_{i}^{x}i*b[i]
i=1∑xj=1∑ib[j]=i=1∑x(x−i+1)∗b[i]=(x+1)i=1∑xb[i]−i∑xi∗b[i]
对于每条指令"C l r d" 执行四个操作:
- 在 c 0 c_0 c0中把 l l l的位置上的数字加上 d d d
- 在 c 0 c_0 c0中把 r + 1 r+1 r+1的位置上的数字加上 − d -d −d
- 在 c 1 c_1 c1中把 l l l的位置上的数字加上 l ∗ d l*d l∗d
- 在 c 1 c_1 c1中把 r + 1 r+1 r+1的位置上的数字加上 − ( r + 1 ) ∗ d -(r+1)*d −(r+1)∗d
对于每条指令"Q l r" 答案为
(
s
u
m
[
r
]
+
(
r
+
1
)
∗
a
s
k
(
c
0
,
r
)
−
a
s
k
(
c
1
,
r
)
)
−
s
u
m
(
[
l
−
1
]
+
l
∗
a
s
k
(
c
0
,
l
−
1
)
−
a
s
k
(
c
1
,
l
−
1
)
)
(sum[r]+(r+1)*ask(c_0,r)-ask(c_1,r)) - sum([l-1]+l*ask(c_0,l-1)-ask(c_1,l-1))
(sum[r]+(r+1)∗ask(c0,r)−ask(c1,r))−sum([l−1]+l∗ask(c0,l−1)−ask(c1,l−1))
code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 100;
typedef long long LL;
template <typename T>
inline void read(T &s) {
s = 0;
T w = 1, ch = getchar();
while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
s *= w;
}
int n, m;
int a[maxn];
LL c[2][maxn], sum[maxn];
inline int lowbit(int x) { return x & (-x); }
inline void add(int k, int x, int y) {
for (; x <= n; x += lowbit(x))
c[k][x] += y;
}
inline LL ask(int k, int x) {
LL ans = 0ll;
for (; x; x -= lowbit(x))
ans += c[k][x];
return ans;
}
int main() {
read(n), read(m);
for (int i = 1; i <= n; ++i) {
read(a[i]);
sum[i] = sum[i - 1] + a[i];
}
while (m--) {
char ch; cin >> ch;
if (ch == 'C') {
int l, r, d;
read(l), read(r), read(d);
add(0, l, d);
add(0, r + 1, -d);
add(1, l, l * d);
add(1, r + 1, -(r + 1) * d);
}
else if (ch == 'Q') {
int l, r;
read(l), read(r);
LL ans = sum[r] + (r + 1) * ask(0, r) - ask(1, r);
// check;
ans -= sum[l - 1] + l * ask(0, l - 1) - ask(1, l - 1);
printf("%lld\n", ans);
}
}
return 0;
}