​POJ - 3468 A Simple Problem with Integers​

题目

线段树裸题

分析

模板,注意下注释部分,累加变量要用long long

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#define INF 0x3f3f3f3f
#define d(x) cout << (x) << endl
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1

// #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 9999991;
const int N = 1e5 + 10;

int n, q, x, y;
char c[10];
ll tr[N << 2], col[N << 2];

void pushup(int rt){
tr[rt] = tr[rt << 1] + tr[rt << 1 | 1];
}

void pushdown(int rt, int m){
ll c = col[rt];
if(c){
col[rt << 1] += c;
col[rt << 1 | 1] += c;
tr[rt << 1] += c * (m - (m >> 1)); //注意左右区间长度
tr[rt << 1 | 1] += c * (m >> 1);
col[rt] = 0;
}
}

void build(int l, int r, int rt){
if(l == r){
scanf("%lld", &tr[rt]); //注意是 tr[rt] 不是 tr[l]
return;
}
int m = l + r >> 1;
build(lson);
build(rson);
pushup(rt);
}

void update(int l, int r, int rt, int L, int R, ll add){
if(L <= l && r <= R){
tr[rt] += (r - l + 1) * add;
col[rt] += add;
return;
}
pushdown(rt, r - l + 1); //每次用到左右儿子都要下放懒惰标记
int m = l + r >> 1;
if(L <= m){
update(lson, L, R, add);
}
if(m < R){
update(rson, L, R, add);
}
pushup(rt);
}

ll query(int l, int r, int rt, int L, int R){
if(L <= l && r <= R){
return tr[rt];
}
ll ans = 0;
int m = l + r >> 1;
pushdown(rt, r - l + 1);
if(L <= m){
ans += query(lson, L, R);
}
if(m < R){
ans += query(rson, L, R);
}
return ans;
}

int main()
{
scanf("%d%d", &n, &q);
build(1, n, 1);
while(q--){
scanf("%s%d%d", &c, &x, &y);
if(c[0] == 'C'){
ll add;
scanf("%lld", &add);
update(1, n, 1, x, y, add);
}else{
printf("%lld\n", query(1, n, 1, x, y));
}
}
return 0;
}

/*
10 5
1 2 3 4 5 6 7 8 9 10
C 3 6 3
Q 2 4

*/