zoukankan      html  css  js  c++  java
  • C++线段树模板(区间和、区间加)

    操作说明:

    • segtree<T>tree(len) =>创建一个内部元素类型为T、区间为1~len的线段树tree
    • tree.build(l,r) =>以[l,r]区间建立线段树
    • tree.update(l,r,val,1,len) =>区间[l,r]所有元素加上val
    • tree.query(l,r,1,len) =>计算区间[l,r]的元素和
    #include <iostream>
    #include <string>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <map>
    #define range(i,a,b) for(auto i=a;i<=b;++i)
    #define LL long long
    #define itrange(i,a,b) for(auto i=a;i!=b;++i)
    #define rerange(i,a,b) for(auto i=a;i>=b;--i)
    #define fill(arr,tmp) memset(arr,tmp,sizeof(arr))
    using namespace std;
    template <class T>
    class segtree{
    private:
        T* add,*sum;
        void pushup(int rt){
            sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        }
        void pushdown(int rt,int m){
            if(add[rt]){
                add[rt<<1]+=add[rt];
                add[rt<<1|1]+=add[rt];
                sum[rt<<1]+=add[rt]*(m-(m>>1));
                sum[rt<<1|1]+=add[rt]*(m>>1);
                add[rt]=0;
            }
        }
    public:
        explicit segtree(int len=int(1e5+5)){
            add=new T[len<<2];
            sum=new T[len<<2];
            fill(add,0);fill(sum,0);
        }
        void build(int l,int r,int rt=1){
            add[rt]=0;
            if(l==r){
                sum[rt]=0;
                return;
            }
            int m=(l+r)>>1;
            build(l,m,rt<<1);
            build(m+1,r,rt<<1|1);
            pushup(rt);
        }
        void update(int L,int R,T c,int l,int r,int rt=1){
            if(L<=l&&r<=R){
                add[rt]+=c;
                sum[rt]+=c*(r-l+1);
                return;
            }
            pushdown(rt,r-l+1);
            int m=(l+r)>>1;
            if(L<=m)update(L,R,c,l,m,rt<<1);
            if(m<R)update(L,R,c,m+1,r,rt<<1|1);
            pushup(rt);
        }
        T query(int L,int R,int l,int r,int rt=1){
            if(L<=l&&r<=R)return sum[rt];
            pushdown(rt,r-l+1);
            int m=(l+r)>>1;
            T ret=0;
            if(L<=m)ret+=query(L,R,l,m,rt<<1);
            if(m<R)ret+=query(L,R,m+1,r,rt<<1|1);
            return ret;
        }
    };
    int main() {
        segtree<int>tree(10);
        tree.build(1,10);
        tree.update(1,5,1,1,10);
        cout<<tree.query(1,5,1,10)<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    javascript面向对象程序设计之浅谈2
    Sphinx学习之sphinx的安装篇
    IT人的职业生涯规划
    perconatoolkit系列之系统类工具的使用
    perconatoolkit系列之实用类工具使用
    查询ip归属地的shell脚本
    使用mysqlsla分析Mysql数据库日志
    MYSQL管理之主从同步管理
    MYSQL数据库管理之权限管理
    perconatoolkit系列之复制类工具使用
  • 原文地址:https://www.cnblogs.com/Rhythm-/p/9373052.html
Copyright © 2011-2022 走看看