题意:区间更新及求和。
思路:模板题。
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int MAXN = 100000 + 10;
ll arr[MAXN], sum[MAXN << 2], add[MAXN << 2];
void PushUp(int rt)
{
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
return;
}
void Build(int l, int r, int rt)
{
add[rt] = 0;
if(l == r)
{
sum[rt] = arr[l];
return;
}
int m = (l + r) >> 1;
Build(l, m, rt << 1);
Build(m + 1, r, rt << 1 | 1);
PushUp(rt);
return;
}
void PushDown(int ln, int rn, int rt)
{
if(add[rt])
{
add[rt << 1] += add[rt];
add[rt << 1 | 1] += add[rt];
sum[rt << 1] += add[rt] * ln;
sum[rt << 1 | 1] += add[rt] * rn;
add[rt] = 0;
}
}
void Update(int L, int R, int c, int l, int r, int rt)
{
if(L <= l && r <= R)
{
sum[rt] += c * (r - l + 1);
add[rt] += c;
return;
}
int m = (l + r) >> 1;
PushDown(m - l + 1, r - m, rt);
if(L <= m) Update(L, R, c, l, m, rt << 1);
if(R > m) Update(L, R, c, m + 1, r, rt << 1 | 1);
PushUp(rt);
return;
}
ll Query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R)
{
return sum[rt];
}
int m = (l + r) >> 1;
PushDown(m - l + 1, r - m, rt);
ll ans = 0;
if(L <= m) ans += Query(L, R, l, m, rt << 1);
if(R > m) ans += Query(L, R, m + 1, r, rt << 1 | 1);
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, q;
cin >> n >> q;
for(int i = 1; i <= n; i++)
{
cin >> arr[i];
}
Build(1, n, 1);
char c;
while(q--)
{
cin >> c;
if(c == 'Q')
{
int a, b;
cin >> a >> b;
cout << Query(a, b, 1, n, 1) << endl;
}
else if(c == 'C')
{
int a, b, c;
cin >> a >> b >> c;
Update(a, b, c, 1, n, 1);
}
}
return 0;
}