概述
lazy 思想就是我这一段在更新的区间内这段更新一下记录一下增加的值到时候子线段要用的时候再用,这样可以节省时间,否则直接更新下去太暴力了会超时
#include<iostream>
#include<algorithm>
using namespace std;
#define ls 2*i
#define rs 2*i+1
#define mid (l+r)/2
#define tmid (T[i].l+T[i].r)/2
const int mx = 1e5+5;
typedef long long int ll;
struct tree{
int l,r;
ll sum,add;
}T[4*mx];
ll a[mx];
ll creat(int i,int l,int r){
T[i].l = l,T[i].r = r;
T[i].add = 0;
if(l == r)
return T[i].sum = a[l];
return T[i].sum = creat(ls,l,mid)+creat(rs,mid+1,r);
}
void pushdown(int i){ //更新
if(T[i].add){
T[ls].add += T[i].add;
T[rs].add += T[i].add;
T[ls].sum += (T[ls].r-T[ls].l+1)*T[i].add;
T[rs].sum += (T[rs].r-T[rs].l+1)*T[i].add;
T[i].add = 0;
}
}
void update(int i,int l,int r,ll x){
if(T[i].l >= l && T[i].r <= r){
T[i].sum += (r-l+1)*x;
T[i].add += x;
return;
}
if(T[i].r < l || T[i].l > r)
return ;
if(T[i].l == T[i].r)
return;
pushdown(i);
//子线段要用更新
if(r <= tmid) update(ls,l,r,x);
else if(l > tmid) update(rs,l,r,x);
else{
update(ls,l,tmid,x);
update(rs,tmid+1,r,x);
}
T[i].sum = T[ls].sum+T[rs].sum;
}
ll query(int i,int l,int r){
if(T[i].r < l || T[i].l > r)
return 0;
if(T[i].l >= l && T[i].r <= r)
return T[i].sum;
pushdown(i); //子线段要用更新一下
return query(ls,l,r)+query(rs,l,r);
}
int n,q;
int main(){
while(cin>>n>>q){
for(int i = 1; i <= n; i++)
cin>>a[i];
creat(1,1,n);
char c;
int l,r;
ll x;
for(int i = 1; i <= q; i++){
cin>>c;
if(c == 'Q'){
cin>>l>>r;
cout<<query(1,l,r)<<endl;
}
else{
cin>>l>>r>>x;
update(1,l,r,x);
}
}
}
return 0;
}
最后
以上就是任性龙猫为你收集整理的POJ3468(线段树+lazy思想)的全部内容,希望文章能够帮你解决POJ3468(线段树+lazy思想)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复