zoukankan      html  css  js  c++  java
  • 线段树

    #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);
            }
        }
    
    }
    int T[maxn],a[maxn];
    void build(int rt,int l,int r){
         if(l == r){
              T[rt] = a[l];
              return;
         }
         int mid = l+r >> 1;
         build(rt<<1,l,mid);
         build(rt<<1|1,mid+1,r);
         T[rt] = max(T[rt<<1],T[rt<<1|1]);
    }
    void modify(int rt,int l,int r,int pos,int val){
         if(l == r){
              T[rt] = val;
              return;
         }     
         int mid = l+r >> 1;
         if(pos <= mid) modify(rt<<1,l,mid,pos,val);
         else modify(rt<<1|1,mid+1,r,pos,val);
         T[rt] = max(T[rt<<1],T[rt<<1|1]);
    }
    int query(int rt,int l,int r,int L,int R){
        if(L <= l && r <= R) return T[rt];
        int mid = l+r >> 1;
        if(R <= mid) return query(rt<<1,l,mid,L,R);
        if(L >  mid) return query(rt<<1|1,mid+1,r,L,R);
        return max(query(rt<<1,l,mid,L,R),query(rt<<1|1,mid+1,r,L,R));
    }
    View Code
  • 相关阅读:
    ORACLE字符串函数
    Ubuntu14.04安装wineqq国际版
    phonegap学习笔记
    Android Studio 1.5.1
    CodeBlocks+Qt(MinGW)配置
    Java多线程之synchronized(五)
    Java多线程之synchronized(四)
    Java多线程之synchronized(三)
    Java多线程之synchronized(二)
    Java多线程之synchronized(一)
  • 原文地址:https://www.cnblogs.com/DWVictor/p/10321710.html
Copyright © 2011-2022 走看看