简单线段树过程详解
#include<iostream>
#include<string.h>
#include<stdlib.h>
#define maxsize 10000
using namespace std;
struct node {
int left, right;
int lazy, sum;
int mid() {
return (left + right) /
2; }
}T[maxsize<<
2];
void pushup(
int rt)
{
T[rt].sum = T[rt <<
1].sum + T[rt <<
1 |
1].sum;
}
void pushdown(
int rt,
int m)
{
if (T[rt].lazy)
{
T[rt <<
1].lazy += T[rt].lazy;
T[rt <<
1 |
1].lazy += T[rt].lazy;
T[rt<<
1].sum += T[rt].lazy*(m - (m >>
1));
T[rt<<
1|
1].sum += T[rt].lazy *(m >>
1);
T[rt].lazy =
0;
}
}
void create(
int rt,
int l,
int r)
{
T[rt].left = l;
T[rt].right = r;
T[rt].lazy =
0;
if (T[rt].left == T[rt].right)
{
cin >> T[rt].sum;
return;
}
create(rt <<
1, l, T[rt].mid());
create(rt <<
1 |
1, T[rt].mid()+
1, r);
pushup(rt);
}
void Union(
int rt,
int l,
int r,
int c)
{
if (T[rt].left == l&&T[rt].right == r)
{
T[rt].lazy += c;
T[rt].sum += c*(T[rt].right - T[rt].left +
1);
return;
}
if (T[rt].left == T[rt].right)
return;
pushdown(rt, T[rt].right - T[rt].left +
1);
if (r <= T[rt].mid())
Union(rt <<
1, l, r, c);
else if (l > T[rt].mid())
Union(rt <<
1 |
1, l, r, c);
else {
Union(rt <<
1, l, T[rt].mid(), c);
Union(rt <<
1 |
1, T[rt].mid()+
1, r, c);
}
pushup(rt);
}
int sum(
int rt,
int l,
int r)
{
int ans=
0;
if (T[rt].left == l&&T[rt].right==r)
return T[rt].sum;
pushdown(rt, T[rt].right - T[rt].left +
1);
if (r <= T[rt].mid())
ans+=sum(rt <<
1, l, r);
else if (l >T[rt].mid())
ans+=sum(rt <<
1 |
1, l, r);
else {
ans+=sum(rt <<
1, l, T[rt].mid());
ans+=sum(rt <<
1 |
1, T[rt].mid()+
1, r);
}
return ans;
}
int main()
{
int n, m, a, b, c;
while (
cin >> n >> m)
{
create(
1,
1,n);
while (m--)
{
char s;
cin >> s;
if (s ==
'Q')
{
cin >> a >> b;
cout << sum(
1, a, b)<<endl;
}
else if(s==
'B'){
cin >> a >> b >> c;
Union(
1, a, b, c);
}
}
}
}