码迷,mamicode.com
首页 > 其他好文 > 详细

POJ-3468(线段树+区间更新+区间查询)

时间:2019-09-02 17:33:08      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:poj   ==   区间   return   name   线段   date   stream   ons   

A Simple Problem With Integers

POJ-3468

  • 这题是区间更新的模板题,也只是区间更新和区间查询和的简单使用。
  • 代码中需要注意的点我都已经标注出来了,容易搞混的就是update函数里面还需要计算sum数组。因为这里查询的时候是直接用sum查询结点。
//区间更新,区间查询
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=100005;
long long num[maxn];
long long sum[maxn<<2];
long long lazy[maxn<<2];
int n,m;
void pushup(int id,int l,int r){
    int lc=id<<1;
    int rc=id<<1|1;
    sum[id]=sum[lc]+sum[rc];
}
void pushdown(int id,int l,int r){
    int lc=id<<1;
    int rc=id<<1|1;
    int mid=(l+r)>>1;
    lazy[lc]+=lazy[id];
    lazy[rc]+=lazy[id];
    sum[lc]+=lazy[id]*(mid-l+1);
    sum[rc]+=lazy[id]*(r-mid-1+1);
    lazy[id]=0;
}
void build(int id,int l,int r){
    if(l==r){
        sum[id]=num[l];
        return;
    }
    int lc=id<<1;
    int rc=id<<1|1;
    int mid=(l+r)>>1;
    build(lc,l,mid);
    build(rc,mid+1,r);
    pushup(id,l,r);//向上维护
}
void update(int id,int l,int r,int p,int q,int v){
    if(p<=l&&q>=r){//完全包含区间
        lazy[id]+=v;
        sum[id]+=v*(r-l+1);//-----------------------这一步容易忘记
        return;
    }
    pushdown(id,l,r);//---------------------这一步也容易忘记
    int mid=(l+r)>>1;
    int lc=id<<1,rc=id<<1|1;
    if(p<=mid){
        update(lc,l,mid,p,q,v);
    }
    if(q>mid){
        update(rc,mid+1,r,p,q,v);
    }
    pushup(id,l,r);
}
long long query(int id,int l,int r,int p,int q){
    long long sums=0;
    if(p<=l&&q>=r){
        //return sums=sum[id]+lazy[id]*(r-l+1);
        return sums=sum[id];
    }
    pushdown(id,l,r);
    int mid=(l+r)>>1;
    if(p<=mid){
        sums+=query(id<<1,l,mid,p,q);
    }
    if(q>mid){
        sums+=query(id<<1|1,mid+1,r,p,q);
    }
    //pushup(id,l,r);//----------因为这里是查询函数,所以可以省略。这里在pushdown函数里面做过类似的。
    return sums;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    while(cin>>n>>m){
        memset(lazy,0,sizeof(lazy));
        for(int i=1;i<=n;i++){
            cin>>num[i];
        }
        build(1,1,n);
        for(int i=0;i<m;i++){
            char c;
            cin>>c;
            if(c=='C'){//add,更新
                int a,b,c;
                cin>>a>>b>>c;
                update(1,1,n,a,b,c);
            }else{//查询
                int a,b;
                cin>>a>>b;
                cout<<query(1,1,n,a,b)<<endl;
            }
        }
    }
    return 0;
}

POJ-3468(线段树+区间更新+区间查询)

标签:poj   ==   区间   return   name   线段   date   stream   ons   

原文地址:https://www.cnblogs.com/GarrettWale/p/11447341.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!