POJ - 3468
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.
Input
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.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
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
Sample Output
4
55
9
15
Hint
The sums may exceed the range of 32-bit integers.
大体意思就是说给你个数,m次操作
Q a b是输出第a个数到第b个数的和
C a b c 是把第a个数到第b个数之间的每一个数都加c
#include<iostream>
#include<cstdio>
#define INF 99999999
using namespace std;
typedef long long LL;//定义LL为long long
struct node
{
LL val;//和
LL len;//长度
LL lazy;//标记
LL l,r;//左右端点
}tree[300005];
LL arr[500005];//暂时储存数据的数组
LL n,m;
void build(LL root,LL l,LL r) //建树
{
LL mid;
tree[root].lazy=0;
tree[root].l=l;tree[root].r=r;
tree[root].len=r-l+1;
if (l==r) tree[root].val=arr[l];//到达树端点,给val赋值
else
{
mid=(l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
tree[root].val=tree[root*2].val+tree[root*2+1].val;
}
}
void pushdown(LL root) //向下传递lazy标记
{
if (tree[root].lazy)
{
tree[root*2].lazy+=tree[root].lazy;
tree[root*2+1].lazy+=tree[root].lazy;
tree[root*2].val+=tree[root*2].len*tree[root].lazy;
tree[root*2+1].val+=tree[root*2+1].len*tree[root].lazy;
tree[root].lazy=0;
}
}
void add(LL root,LL id,LL addval) //单点更新
{
LL mid;
if (tree[root].l==tree[root].r)
{
tree[root].val+=addval;
return;
}
else
{
mid=(tree[root].l+tree[root].r)/2;
if (id<=mid) add(root*2,id,addval);
else add(root*2+1,id,addval);
tree[root].val=tree[root*2].val+tree[root*2+1].val;
}
}
LL query(LL root,LL l,LL r) //计算区间和
{
LL mid;
if (tree[root].l>=l&&tree[root].r<=r)
return tree[root].val;
if (tree[root].l>r||tree[root].r<l)
return 0;
if (tree[root].lazy) pushdown(root);
return query(root*2,l,r)+query(root*2+1,l,r);
}
void update(LL root,LL l,LL r,LL addval) //区间更新
{
LL mid;
if (tree[root].l>=l&&tree[root].r<=r)
{
tree[root].lazy+=addval;
tree[root].val+=tree[root].len*addval;
return;
}
if (tree[root].l>r||tree[root].r<l)
return;
if (tree[root].lazy) pushdown(root);
update(root*2,l,r,addval);
update(root*2+1,l,r,addval);
tree[root].val=tree[root*2].val+tree[root*2+1].val;
}
int main()
{
LL i,x,y,k;
char ch;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
{
scanf("%lld",&arr[i]);
}
build(1,1,n);
for (i=1;i<=m;i++)
{
scanf(" %c",&ch);
if (ch=='C')
{
scanf("%lld%lld%lld",&x,&y,&k);
update(1,x,y,k);
}
else
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,x,y));
}
}
}
加入了lazy标记,暂时储存每次更新的数;