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

线段树

时间:2019-01-25 21:45:01      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:等于   update   c++   its   递归   int   bsp   while   lse   

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5; //1~1e5
int sum[maxn << 2]; //用节点维护区间的和
int a[maxn];
int lazy[maxn << 2];

//5~101  5*4=20
//10100 2^4+2^2
//20

void push_up(int rt) {
    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    return;
    //当前节点的信息等于当前节点的左儿子和右儿子的信息之和
}
void push_down(int rt,int mid){
    if(lazy[rt]){
        lazy[rt<<1]+=lazy[rt];
        lazy[rt<<1|1]+=lazy[rt];
        sum[rt<<1]+=lazy[rt]*(mid-(mid>>1));
        sum[rt<<1|1]+=lazy[rt]*mid;
        lazy[rt]=0;
    }    
    return;
}
void build(int l, int r, int rt) {//当前区间是[l,r],当前的根节点是rt
    if(l == r) {
        sum[rt] = 0;
        return;
    }
    int mid = (l + r) >> 1;
    // 除以2
    build(l, mid, rt << 1);
    build(mid + 1, r, rt << 1 | 1); //zou wan le
    push_up(rt); //使得节点rt 得到信息
}

void update(int L, int R, int val, int l, int r, int rt) {
    if(L <= l && r <= R) {
        lazy[rt]+=val; 
        return;
    }
    int mid = (l + r) >> 1;
    push_down(rt,mid);//将节点的lazy标记给递推下去,将加法变成乘法
    if(L <= mid) {
        update(L,R,val, l, mid, rt << 1);
    }
    if(R > mid) {
        update(L,R,val, mid + 1, r, rt << 1 | 1);
    }
    push_up(rt);
}
int query(int L, int R, int l, int r, int rt) { //我需要查询的区间是[L,R],我当前的区间是(l,r),当前的根是rt
    if(L <= l && r <= R) {
        //我递归到的区间在我的所需要查询的区间里面,我就要得到这个递归到的区间的信息
        return sum[rt];
    }
    push_down(rt);
    int ans = 0;
    int mid = (l + r) >> 1;
    if(L <= mid) ans += query(L, R, l, mid, rt << 1);
    if(R > mid) ans += query(L, R, mid + 1, r, rt << 1);
    return ans;
}
int main() {
    int n, q;
    cin >> n >> q;
    for(int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
    }
    build(1, n, 1);
    while(q--) {
        int op, l, r;
        scanf("%d", &op);
        if(op == 1) {
            scanf("%d%d", &l, &r);
            //得到区间l,r的信息
            int ans = query(l, r, 1, n, 1);
        } else {
            int val;
            scanf("%d%d%d", &l, &r,&val);
            update(l, r, val, 1, n, 1);
        }
    }

}

 

线段树

标签:等于   update   c++   its   递归   int   bsp   while   lse   

原文地址:https://www.cnblogs.com/DWVictor/p/10321710.html

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