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

    2017-08-30 19:53:27

    writer:pprp

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define MAXN 10000
    
    struct Tree
    {
        int val;//此区间存的值
        int addnum;//整个区间被增加的值
        bool lazy;//区间是否被整体修改过
        int lazy_chg;//区间被整体修改后的值(lazy==true时有效)
    } tree[MAXN*4];
    
    int arr[MAXN];//用于初始化的数组
    
    int lson(int rt)
    {
        return rt<<1;
    }
    
    int rson(int rt)
    {
        return (rt<<1)|1;
    }
    
    //更新此区间存的值
    //@param: rt:根的编号
    void tree_update(int rt)
    {
        tree[rt].val=max(tree[lson(rt)].val,tree[rson(rt)].val)+tree[rt].addnum;
        //可更改(max/min/sum)
    }
    
    //将编号rt的区间全变为val
    //@param: 
    void tree_chg(int left,int right,int rt,int val)
    {
        tree[rt].val=val;/**可更改(求和则为v*(right-left+1))**/
        tree[rt].lazy=true;
        tree[rt].lazy_chg=val;
        tree[rt].addnum=0;
    }
    
    //将整体修改的信息向下传递
    void pushDown(int left,int right,int rt)
    {
        if(tree[rt].lazy)
        {
            tree[rt].lazy=false;
            int mid=(left+right)>>1;
            tree_chg(left,mid,lson(rt),tree[rt].lazy_chg);
            tree_chg(mid+1,right,rson(rt),tree[rt].lazy_chg);
        }
    }
    
    void tree_init()
    {
        memset(tree,0,sizeof(tree));//清0
    }
    
    //建立一个线段树
    void tree_build(int left,int right,int rt)//初始化维护某个数组
    {
        tree[rt].lazy=false;
        tree[rt].addnum=0;
        if(left==right)
        {
            tree[rt].val=arr[left];/**需对应为原数组的名称**/
        }
        else
        {
            int mid=(left+right)>>1;
            tree_build(left,mid,lson(rt));
            tree_build(mid+1,right,rson(rt));
            tree_update(rt);
        }
    }
    
    //区间增加
    //把l到r间的值都增加v
    void tree_add(int left,int right,int rt,int l,int r,int val)
    {
        if(l<=left&&right<=r)
        {
            tree[rt].val+=val;
            tree[rt].addnum+=val;
        }
        else
        {
            pushDown(left,right,rt);
            int mid=(left+right)>>1;
            if(l<=mid)tree_add(left,mid,lson(rt),l,r,val);
            if(r>mid)tree_add(mid+1,right,rson(rt),l,r,val);
            tree_update(rt);
        }
    }
    
    //区间修改
    //把l到r间的值都修改为v
    void tree_change(int left,int right,int rt,int l,int r,int v)
    {
        if(l<=left&&right<=r)tree_chg(left,right,rt,v);
        else
        {
            pushDown(left,right,rt);
            int mid=(left+right)>>1;
            if(l<=mid)tree_change(left,mid,lson(rt),l,r,v);
            if(r>mid)tree_change(mid+1,right,rson(rt),l,r,v);
            tree_update(rt);
        }
    }
    
    //区间查询
    //查询区间[l,r]维护的值
    int tree_find(int left,int right,int rt,int l,int r,int val)
    {
        if(l<=left&&right<=r)return tree[rt].val;
        else
        {
            pushDown(left,right,rt);
            int mid=(left+right)>>1;
            if(l<=mid&&r>mid)
                return max(tree_find(left,mid,lson(rt),l,r,val)
                           ,tree_find(mid+1,right,rson(rt),l,r,val));
            /**可更改(max/min/sum)**/
            if(l<=mid)return tree_find(left,mid,lson(rt),l,r,val);
            return tree_find(mid+1,right,rson(rt),l,r,val);
        }
    }
    
    int main()
    {
    
        return 0;
    }
  • 相关阅读:
    ModelForm详解
    form中choice从数据库实时更新
    django-form字段和插件widgets速查
    Form生成的label标签详解
    form+ajax实现验证
    微分方程的解
    easyui中连接按钮样式
    easyui中设置开始日期只能选择比结束日期小的日期,js代码获取日期的值
    三目表达式问题
    easyui中在formatter: function (value, row,index) {中添加删除方法
  • 原文地址:https://www.cnblogs.com/pprp/p/7455015.html
Copyright © 2011-2022 走看看