题目大意:
区间更新,区间查找。
解题思路:
注意数据范围,然后线段树lazy标记就行了,很基础,没什么技巧。
#include<stdio.h>
#define N 100005
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define node rt,l,r
__int64 value[N];
struct Node{
__int64 k;
__int64 v;
};
Node tree[N*4];
void up(int rt)
{
tree[rt].v=tree[rt<<1].v+tree[rt<<1|1].v;
}
void build(int rt,int l,int r)
{
tree[rt].k=0;
if(l==r)
{
tree[rt].v=value[l];
return ;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
up(rt);
}
void down(int rt,int l,int r)
{
long long k=tree[rt].k;//这个地方没有用64错了好多次。。。
if(k!=0)
{
tree[rt<<1].k+=k;tree[rt<<1|1].k+=k;///不能可能前面待更新的不止一个
int mid=(l+r)>>1;
tree[rt<<1].v+=(mid-l+1)*k;
tree[rt<<1|1].v+=(r-mid)*k;
tree[rt].k=0;
}
}
__int64 Query(int rt, int l, int r, int a, int b)
{
if(a<=l&&r<=b)
{
return tree[rt].v;
}
down(node);
int mid=(l+r)>>1;
if(b<=mid)
return Query(lson,a,b);
else if(a>mid)
return Query(rson,a,b);
else
{
return Query(lson,a,b)+Query(rson,a,b);
}
up(rt);
}
void add(int rt,int l,int r,int a,int b,__int64 c)
{
if(l>=a&&r<=b)
{
tree[rt].k+=c;
tree[rt].v+=(r-l+1)*c;
return ;
}
down(node);
int mid=(l+r)>>1;
if(b<=mid)
add(lson,a,b,c);
else if(a>mid)
add(rson,a,b,c);
else{
add(lson,a,b,c);
add(rson,a,b,c);
}
up(rt);
}
int main()
{
int n,m,i,a,b;
__int64 c,ans;
char op[10];
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%I64d",&value[i]);
build(1,1,n);
while(m--){
scanf("%s",&op);
if(op[0]=='Q'){
scanf("%d%d",&a,&b);
ans=Query(1,1,n,a,b);
printf("%I64d\n",ans);
}else{
scanf("%d%d%I64d",&a,&b,&c);
add(1,1,n,a,b,c);
}
}
return 0;
}