POJ 3468 - A Simple Problem with Integers(线段树区间更新)
题目链接 https://cn.vjudge.net/problem/POJ-3468
【题意】
给定长度为 的序列 ,有 次操作,操作分两种
表示将序列中 所有元素都加上一个数字
表示查询序列 的元素之和
【思路】
线段树区间更新,维护区间和并用lazy标记进行区间更新
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define node tree[id]
#define lson tree[id<<1]
#define rson tree[id<<1|1]
using namespace std;
typedef long long ll;
const int maxn=100005;
struct Tree{
int left,right;
ll sum,lazy;
}tree[maxn<<2];
int n,q;
ll a[maxn];
void pushup(int id){node.sum=lson.sum+rson.sum;}
void pushdown(int id){
if(node.lazy && node.left!=node.right){
lson.lazy+=node.lazy;
lson.sum+=node.lazy*(ll)(lson.right-lson.left+1);
rson.lazy+=node.lazy;
rson.sum+=node.lazy*(ll)(rson.right-rson.left+1);
node.lazy=0;
}
}
void build(int id,int le,int ri){
node.left=le;
node.right=ri;
node.lazy=0;
if(le==ri){
node.sum=a[le];
return;
}
int mid=(le+ri)>>1;
build(id<<1,le,mid);
build(id<<1|1,mid+1,ri);
pushup(id);
}
ll query(int id,int le,int ri){
if(node.left==le && node.right==ri){
return node.sum;
}
pushdown(id);
int mid=(node.left+node.right)>>1;
if(ri<=mid) return query(id<<1,le,ri);
else if(le>mid) return query(id<<1|1,le,ri);
else return query(id<<1,le,mid)+query(id<<1|1,mid+1,ri);
}
void update(int id,int le,int ri,ll val){
if(node.left==le && node.right==ri){
node.sum+=val*(ll)(node.right-node.left+1);
node.lazy+=val;
return;
}
pushdown(id);
int mid=(node.left+node.right)>>1;
if(ri<=mid) update(id<<1,le,ri,val);
else if(le>mid) update(id<<1|1,le,ri,val);
else{
update(id<<1,le,mid,val);
update(id<<1|1,mid+1,ri,val);
}
pushup(id);
}
int main(){
while(scanf("%d%d",&n,&q)==2){
for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
build(1,1,n);
while(q--){
char op[2];
scanf("%s",op);
if(op[0]=='Q'){
int a,b;
scanf("%d%d",&a,&b);
printf("%lld\n",query(1,a,b));
}
else{
int a,b;
ll c;
scanf("%d%d%lld",&a,&b,&c);
update(1,a,b,c);
}
}
}
return 0;
}