#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int maxn = 100010;
LL sumtr[maxn<<2];
LL add[maxn<<2];
void build(int l, int r, int rt);
void pushup(int rt);
LL query(int L, int R, int l, int r, int rt);
void update(int L, int R, int x, int l, int r, int rt);
void pushdown(int rt, int len);
int main()
{
int i;
int n, q;
while(~scanf("%d %d", &n, &q))
{
build(1, n, 1);
char ch;
int a, b, c;
while(q--)
{
getchar();
scanf("%c", &ch);
if(ch == 'Q')
{
scanf("%d %d", &a, &b);
LL ans = query(a, b, 1, n, 1);
printf("%lld\n", ans);
}
else
{
scanf("%d %d %d", &a, &b, &c);
update(a, b, c, 1, n, 1);
}
}
}
return 0;
}
void pushdown(int rt, int len)
{
if(!add[rt]) return;
add[rt<<1] += add[rt];
add[rt<<1|1] += add[rt];
sumtr[rt<<1] += add[rt] * (len - (len>>1));
sumtr[rt<<1|1] += add[rt] * (len>>1);
add[rt] = 0;
}
void update(int L, int R, int x, int l, int r, int rt)
{
if(L <= l && r <= R)
{
add[rt] += x;
sumtr[rt] += (LL)x * (r - l + 1);
return;
}
pushdown(rt, r - l + 1);
int mid = (l + r)>>1;
if(L <= mid) update(L, R, x, l, mid, rt<<1);
if(R >= mid + 1) update(L, R, x, mid + 1, r, rt<<1|1);
pushup(rt);
}
LL query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R) return sumtr[rt];
pushdown(rt, r - l + 1);
int mid = (l + r)>>1;
LL ret = 0;
if(L <= mid) ret += query(L, R, l, mid, rt<<1);
if(R >= mid + 1) ret += query(L, R, mid + 1, r, rt<<1|1);
return ret;
}
void pushup(int rt)
{
sumtr[rt] = sumtr[rt<<1] + sumtr[rt<<1|1];
}
void build(int l, int r, int rt)
{
add[rt] = 0;
if(l == r)
{
scanf("%lld", &sumtr[rt]);
return;
}
int mid = (l + r)>>1;
build(l, mid, rt<<1);
build(mid + 1, r, rt<<1|1);
pushup(rt);
}
线段树poj3468_区间增减更新
最新推荐文章于 2019-01-16 18:10:40 发布