题目传送门
A题:
带lazy标记的线段树,不多说;
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MaxN = 100000 + 5;
long long sum[4 * MaxN];
long long lazy[4 * MaxN] = {0};
int n,q;
void build(int p, int l, int r, int i ,long long t);
void add (int p, int l, int r, int tl, int tr, long long t);
void pushdown (int p, int l, int r);
long long query(int rt, int l, int r, int ql, int qr);
int main()
{
scanf("%d%d", &n, &q);
long long input;
for(int i=1; i<=n; i++){
cin >> input ;
build(1, 1, n, i, input);
}
char ch;
int a, b, c;
for (int i=0; i<q; i++){
scanf(" %c ", &ch);
if(ch == 'C'){
scanf("%d%d%d", &a, &b, &c);
add(1, 1, n, a, b, c);
}
else{
scanf("%d%d", &a, &b);
cout << query(1, 1, n, a, b) << endl;
}
}
return 0;
}
void build(int p, int l, int r, int i ,long long t)
{
if(l == r) {sum[p] = t;return;}
int mid = (l + r) >> 1;
if(i <= mid) build(2 * p, l, mid, i, t);
else build(2 * p + 1, mid + 1, r, i, t);
sum[p] = sum[2 * p] + sum[2 * p + 1];
}
void add (int p, int l, int r, int tl, int tr, long long t)
{
if(tl <= l && tr >= r) {lazy[p] += (r - l + 1) * t; sum[p] += (r - l + 1) * t; return;}
if(lazy[p]) pushdown(p, l, r);
int mid = (l + r) >> 1;
if(tl <= mid) add(2 * p, l, mid, tl, tr, t);
if(tr > mid) add(2 * p + 1, mid + 1, r, tl, tr, t);
sum[p] = sum[2 * p + 1] + sum[2 * p];
}
void pushdown (int p, int l, int r)
{
long long temp = lazy[p] / (r - l + 1);
int mid = (l + r) >> 1;
long long sum1 = temp * (mid - l + 1);
long long sum2 = lazy[p] - sum1;
sum[2 * p] += sum1, sum[2 * p + 1] += sum2;
lazy[p] = 0;
lazy[2 * p] += sum1, lazy[2 * p + 1] += sum2;
}
long long query(int rt, int l, int r, int ql, int qr)
{
if(ql <= l && qr >= r) return sum[rt];
if(lazy[rt]) pushdown(rt, l, r);
int mid = (l + r) >> 1;
if(qr <= mid) return query(2 * rt, l, mid, ql, qr);
if(ql > mid) return query(2 * rt + 1, mid + 1, r, ql, qr);
long long ans = query(2 * rt, l, mid , ql, qr) + query(2 * rt + 1, mid + 1, r, ql, qr);
return ans;
}