线段树求和
作者:互联网
P1003: A Simple Problem with Integers
题目描述
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
输入
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
输出
You need to answer all Q commands in order. One answer in a line.
样例输入
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
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<algorithm>
//理解结点标号,结点的左右结点标号是当前结点的2倍和2倍加1,一个结点的区间范围由结点的l和r唯一确定
//这两个概念不应该混为一谈
#define lson (x<<1)
#define rson ((x<<1)|1)
const int N = 100005;
typedef long long ll;
typedef struct node
{
int l, r;
ll val, lazy;
}node;
node tree[N * 4];
ll a[N];
int n;
void PushUp(int x)
{
tree[x].val = tree[lson].val + tree[rson].val;
}
void PushDown(int x)
{
if (tree[x].lazy) {
tree[lson].lazy += tree[x].lazy;
tree[rson].lazy += tree[x].lazy;
tree[lson].val += tree[x].lazy * (tree[lson].r - tree[lson].l + 1);
tree[rson].val += tree[x].lazy * (tree[rson].r - tree[rson].l + 1);
tree[x].lazy = 0;
}
}
void Build(int x, int l, int r)//l和r分别是编号为x的结点左区间和右区间
{
tree[x].l = l, tree[x].r = r, tree[x].lazy = 0;
if (l == r) {
tree[x].val = a[l]; return;
}
int mid = (l + r) / 2;
Build(lson, l, mid);
Build(rson, mid + 1, r);
PushUp(x);
}
void Update(int x, int l, int r, int add)
{
if (tree[x].l >= l && tree[x].r <= r) {
tree[x].lazy += add;
tree[x].val += (tree[x].r - tree[x].l + 1) * add;
return;
}
PushDown(x);
int mid = (tree[x].l + tree[x].r) / 2;
if (l <= mid)Update(lson, l, r, add);
if (mid < r)Update(rson, l, r, add);
PushUp(x);
return;
}
ll Query(int x, int l, int r)
{
if (tree[x].l >= l && tree[x].r <= r)return tree[x].val;
PushDown(x);
int mid = (tree[x].l + tree[x].r) / 2;
if (r <= mid)return Query(lson, l, r);
else if (l > mid)return Query(rson, l, r);
else return Query(lson, l, r) + Query(rson, l, r);
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)scanf("%lld", &a[i]);
Build(1, 1, n);
for (int i = 0; i < m; i++) {
char temp;
int x, y;
ll val;
scanf("\n%c %d %d", &temp, &x, &y);//读取一个换行
if (temp == 'C')
{
scanf("%lld", &val);
Update(1, x, y, val);
}
else {
printf("%lld\n", Query(1, x, y));
}
}
}
标签:Aa,...,结点,求和,线段,given,Query,line 来源: https://www.cnblogs.com/tzp-empty-hya/p/15832086.html