#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 100100
#define ls rt<<1
#define rs ls|1
#define m (r+l)>>1
long long sum[MAX << 2];
long long tg[MAX << 2];
void uprt(long long rt)
{
sum[rt] = sum[rs] + sum[ls];
}
void ups(long long rt, long long l)
{
if (tg[rt])
{
sum[ls] += tg[rt] * (l - (l >> 1));
sum[rs] += tg[rt] * (l >> 1);
//下一次也可能只加到这边,所以这边要用加的不能用赋值的
//赋值让我wa了10次,而且难检查
tg[ls] += tg[rt];
tg[rs] += tg[rt];
tg[rt] = 0;
}
}
void build(long long l, long long r, long long rt)
{
tg[rt] = 0;
if (l == r)
{
scanf("%lld", &sum[rt]);
return;
}
long long mid = m;
build(l, mid, ls);
build(mid + 1, r, rs);
uprt(rt);
}
void updata(long long p, long long L, long long R, long long l, long long r, long long rt)
{
if (L <= l&&r <= R)
{
sum[rt] += p*(r - l + 1);
//下一次也可能只加到这边,所以这边要用加的不能用赋值的
//赋值让我wa了10次,而且难检查
tg[rt] += p;
return;
}
ups(rt, r - l + 1);
long long mid = m;
if (mid >= L)
updata(p, L, R, l, mid, ls);
if (mid < R)
updata(p, L, R, mid + 1, r, rs);
uprt(rt);
}
long long query(long long L, long long R, long long l, long long r, long long rt)
{
if (L <= l&&r <= R)
return sum[rt];
ups(rt, r-l + 1);
long long mid = m;
long long ans = 0;
if (mid >= L)
ans += query(L, R, l, mid, ls);
if (mid < R)
ans += query(L, R, mid + 1, r, rs);
return ans;
}
int main()
{
long long n, k;
cin >> n >> k;
build(1, n, 1);
char str[3];
long long a, b,c;
while (k--)
{
scanf("%s", str);
if (str[0] == 'Q')
{
scanf("%lld%lld", &a, &b);
cout << query(a, b, 1, n, 1) << endl;
}
else
{
scanf("%lld%lld%lld", &a, &b, &c);
updata(c, a, b, 1, n, 1);
}
}
return 0;
}
【POJ】3468 (线段树,区间成段按需更新)
最新推荐文章于 2018-10-06 16:51:44 发布