思路:
线段树区间修改,然后让你求区间和的问题,但是题目有大坑,注意-1000000000≤ Ai ≤1000000000,要用long long型,虽然操作C增加c的范围只有-10000 ≤ c ≤ 10000,但是与它相关的参数都必须也要用long long型。。。注意了这个,剩下的就是线段树区间修改了。。。
ACcode:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
#define N 1000100
struct node
{
LL l;
LL r;
LL sum;
LL lazy; //lazy标记记录更新值
}tree[N<<2];
LL a[N];
void pushdown(LL root, LL len)
{
if (tree[root].lazy)
{ //将标记传递给左右子树
tree[root * 2].lazy += tree[root].lazy;
tree[root * 2 + 1].lazy += tree[root].lazy; // 更新左右子树的sum
tree[root * 2].sum += tree[root].lazy*(len - (len / 2));
tree[root * 2 + 1].sum += tree[root].lazy*(len / 2);
tree[root].lazy = 0; //注意标记清空
}
}
void build(LL root, LL l, LL r)
{
tree[root].l = l;
tree[root].r = r;
tree[root].lazy = 0; // lazy标记初始化
if (l == r) { tree[root].sum = a[l]; return; }
LL mid = (l + r) / 2;
build(root * 2, l, mid);
build(root * 2 + 1, mid + 1, r);
tree[root].sum = tree[root * 2].sum + tree[root * 2 + 1].sum;
}
void update(LL root, LL l, LL r, LL c)
{
int mid = (tree[root].r + tree[root].l) / 2;
if (tree[root].l >= l&&tree[root].r <= r)
{
tree[root].lazy += c;
//更新本区间sum ,不然连续两次update会将标记堆积,而c值不同导致更新错误
tree[root].sum += c*(tree[root].r - tree[root].l + 1);
return;
}
//将标记传递给左右子树,不然连续两次update会将标记堆积,而c值不同导致更新错误
pushdown(root, tree[root].r - tree[root].l + 1);
if (l <= mid)
{
update(root * 2, l, r, c);
}
if (mid<r)
{
update(root * 2 + 1, l, r, c);
}
tree[root].sum = tree[root * 2].sum + tree[root * 2 + 1].sum;
}
LL query(LL root,LL l,LL r)
{
int mid = (tree[root].l + tree[root].r) / 2;
LL ans = 0;
if (tree[root].l >= l&&tree[root].r <= r)
{
return tree[root].sum;
}
//查询时将父亲节点的lazy传递给左右子树,更新区间,保证被查询的区间被已经被更新
pushdown(root, tree[root].r - tree[root].l + 1);
if (l <= mid)
{
ans += query(root * 2, l, r);
}
if (r>mid)
{
ans += query(root * 2 + 1, l, r);
}
tree[root].sum = tree[root * 2].sum + tree[root * 2 + 1].sum;
return ans;
}
int main()
{
LL i, x, y, z, n, m;
char ch[10];
while (scanf("%lld%lld", &n, &m) != EOF)
{
for (i = 1; i <= n; i++)
scanf("%lld", &a[i]);
build(1, 1, n);
for (i = 0; i<m; i++)
{
scanf("%s", ch);
if (ch[0] == 'Q')
{
scanf("%lld%lld", &x, &y);
printf("%lld\n", query(1, x, y));
}
else
{
scanf("%lld%lld%lld", &x, &y, &z);
update(1, x, y, z);
}
}
}
return 0;
}