线段树区间更新

#include <bits/stdc++.h>
using namespace std;
int n,tre[10003*4],int laz[10003*4];
void pushdown(int num){
    if(laz[num]!=0){
        tre[num*2]+=laz[num];
        tre[num*2+1]+=laz[num];
        laz[num*2]+=laz[num];
        laz[num*2+1]+=laz[num];
        laz[num]=0;
    }
}
void update(int num,int le,int ri,int x,int y){
    if(x<=le&&y>=ri){
        tre[num]++; laz[num]++; return ;
    }
    pushdown(num);
    int mid=(le+ri)/2;
    if(x<=mid) update(num*2,le,mid,x,y);
    if(y>mid) update(num*2+1,mid+1,ri,x,y);
}
int query(int num,int le,int ri,int x){
if(le==ri) return tre[num];
    pushdown(num);
    int mid=(le+ri)/2;
    if(x<=mid) return query(num*2,le,mid,x);
    else return query(num*2+1,mid+1,ri,x);
}
int main(void){
    while(scanf("%d",&n)==1&&n!=0){
        memset(tre,0,sizeof(tre));
        memset(laz,0,sizeof(laz));
        for(int i=0;i<n;i++){
            int a,b; cin>>a>>b;
            update(1,1,n,a,b);
        }
        for(int i=1;i<=n;i++){
            cout<<query(1,1,n,i);
            if(i==n)cout<<endl;
            else cout<<' ';
        }
    }
    return 0;
}
线段树区间更新
题目:HDU1556
给出n个区间,每个区间内的值+1,最后输出[1,n]中点值,当n为0时结束

解释:
pushdown函数
对每个结点操作前不管三七二十一都先pushdown一下,若发现其laz值非0就表示需要pushdown了,其左右儿子的laz及tre都要累加

update与query除了多了上面的函数外与单点更新一样,本例中开始时[1,n]都是0所以不用build

Input	output
3		1 1 1
1 1		3 2 1
2 2
3 3
3
1 1
1 2
1 3
0

精简模板区间更新区间求和

#include <bits/stdc++.h>
using namespace std;
int n,tre[10003*4],laz[10003*4];
void pushdown(int num){
    tre[num*2]+=laz[num];
    tre[num*2+1]+=laz[num];
    laz[num*2]+=laz[num];
    laz[num*2+1]+=laz[num];
    laz[num]=0;
}
void update(int num,int le,int ri,int x,int y){
    if(x<=le&&y>=ri){
        tre[num]++; laz[num]++; return ;
    }
    pushdown(num);
    int mid=(le+ri)/2;
    if(x<=mid) update(num*2,le,mid,x,y);
    if(y>mid) update(num*2+1,mid+1,ri,x,y);
    tre[num]=tre[num*2]+tre[num*2+1];
}
int query(int num,int le,int ri,int x,int y){
    if(x<=le&&ri<=y) return tre[num];
    pushdown(num);
    int mid=(le+ri)/2;
    int ans=0;
    if(x<=mid)ans+=query(num*2,le,mid,x,y);
    if(y>mid)ans+=query(num*2+1,mid+1,ri,x,y);
    return ans;
}
int main(void){
    cin>>n;
    for(int i=1;i<=4;i++){
        int x,y;cin>>x>>y;
        update(1,1,5,x,y);
    }
    cout<<query(1,1,n,1,1)<<endl;//2
    cout<<query(1,1,n,2,2)<<endl;//3
    cout<<query(1,1,n,3,3)<<endl;//4
    cout<<query(1,1,n,4,4)<<endl;//3
    cout<<query(1,1,n,5,5)<<endl;//2
    cout<<'*'<<endl;
    cout<<query(1,1,n,1,2)<<endl;//5
    cout<<query(1,1,n,2,3)<<endl;//7
    cout<<query(1,1,n,3,4)<<endl;//7
    cout<<query(1,1,n,4,5)<<endl;//5
    cout<<'*'<<endl;
    cout<<query(1,1,n,2,4)<<endl;//10
    cout<<query(1,1,n,1,5)<<endl;//14
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值