首页 > 其他分享 >线段树高阶学习指南

线段树高阶学习指南

时间:2023-10-14 09:14:23浏览次数:36  
标签:学习指南 return int 线段 tree mid st 高阶 ll

前置芝士

线段树基本框架

区间求和

const int N=100010;
ll a[N],st[N*4],f[N*4];
int n,q;
//向上传
void pushup(ll u){
    st[u]=st[lc]+st[rc];
}
//向下传
void pushdown(ll u,ll l,ll r,ll mid){
    if(f[u]){
        st[lc]+=f[u]*(mid-l+1);
        st[rc]+=f[u]*(r-mid);
        f[lc]+=f[u];
        f[rc]+=f[u];
        f[u]=0;
    }
}
//初始化
void build(ll u,ll l,ll r){
    if(l==r){
        st[u]=a[l];
        return;
    }
    ll mid=l+r>>1;
    build(lc,l,mid);
    build(rc,mid+1,r);
    pushup(u);
}
//区间更新
void update(ll u,ll l,ll r,ll x,ll y,ll k){
    if(x>r||y<l) return;
    if(x<=l&&y>=r){
        st[u]+=(r-l+1)*k;
        f[u]+=k;
        return;
    }
    ll mid=l+r>>1;
    pushdown(u,l,r,mid);
    update(lc,l,mid,x,y,k);
    update(rc,mid+1,r,x,y,k);
    pushup(u);
}
//区间查询
ll query(ll u,ll l,ll r,ll x,ll y){
    if(x>r||y<l) return 0;
    if(x<=l&&r<=y) return st[u];
    ll mid=l+r>>1;
    pushdown(u,l,r,mid);
    return query(lc,l,mid,x,y)+query(rc,mid+1,r,x,y);
}
//build(1,1,n);
//update(1,1,n,l,r,k);
//query(1,1,n,l,r);

区间最值

[python]

class Tree():
    def __init__(self):
        self.l=0
        self.r=0
        self.lazy=0
        self.val=0

tree=[Tree() for i in range(10*4)]
def build(p,l,r):
    if l>r:
        return
    tree[p].l, tree[p].r, tree[p].lazy, tree[p].val = l, r, 0, 0
    if l<r:
        mid=(l+r)>>1
        build(p<<1,l,mid)
        build(p<<1|1,mid+1,r)
def pushUp(p):
    tree[p].val=max(tree[p<<1].val,tree[p<<1|1].val)


#单点修改,添加值
def add(p,i,v):
    if tree[p].l==tree[p].r:
        tree[p].val+=v
    else:
        mid=(tree[p].l+tree[p].r)>>1
        if i>mid:
            add(p<<1|1,i,v)
        else:
            add(p<<1,i,v)
        pushUp(p)
def pushdown(p):
    if tree[p].lazy:
        lazy=tree[p].lazy
        tree[p<<1].lazy+=lazy
        tree[p<<1|1].lazy+=lazy
        tree[p<<1].val+=lazy
        tree[p<<1|1].val+=lazy
        tree[p].lazy=0
def update(p,l,r, v):
    if l<=tree[p].l and r>=tree[p].r:
        tree[p].lazy+=v
        tree[p].val+=v
        return
    if r<tree[p].l or l>tree[p].r:
        return
    if tree[p].lazy:
        pushdown(p)
    update(p<<1,l,r,v)
    update(p<<1|1,l,r,v)
    pushUp(p)

def query(p,l,r):
    if l<=tree[p].l and r>=tree[p].r:
        return tree[p].val
    if tree[p].l>r or tree[p].r<l:
        return 0
    if tree[p].lazy:
        pushdown(p)
    return max(query(p<<1,l,r),max(p<<1|1,l,r))
build(1,1,10)
update(1,1,5,1)
update(1,7,10,1)
update(1,2,8,1)
update(1,3,4,1)
update(1,9,10,1)
print(query(1,1,10))

[java]

class SegTree{
    static final int INF=0x3f3f3f3f;
    final int n;
    final int[] min,lazy;

    SegTree(int n) {
        this.n=n;
        min=new int[n<<2];
        lazy=new int[n<<2];
        Arrays.fill(min,INF);
        Arrays.fill(lazy,INF);
    }
    void build(int[] a){
        build(1,0,n-1,a);
    }
    void build(int p,int l,int r,int[] a){
//        if(l>r) return;
        if(l==r){
            min[p]=a[l];
            return;
        }
        int mid=(l+r)>>1;
        build(p<<1,l,mid,a);
        build(p<<1|1,mid+1,r,a);
        min[p]=Math.min(min[p<<1],min[p<<1|1]);
    }
    void update(int i,int j,int val){
        if(i>j) return;
        update(i,j,val,0,n-1,1);
    }
    void update(int i,int j,int val,int st,int ed,int p){
        if(i<=st && j>=ed){
            min[p]=Math.min(min[p],val);
            lazy[p]=Math.min(lazy[p],val);
            return;
        }
        pushDown(p);
        int mid=(st+ed)>>1;
        if(i<=mid) update(i,j,val,st,mid,p<<1);
        if(j>mid) update(i,j,val,mid+1,ed,p<<1|1);
        pushUp(p);
    }
    int query(int i){
        return query(0,i,0,n-1,1);
    }
    int query(int i,int j){
        return query(i,j,0,n-1,1);
    }
    int query(int i,int j,int st,int ed,int p){
        if(i<=st && j>=ed){
            return min[p];
        }
        pushDown(p);
        int ans=INF;
        int mid=(st+ed)>>1;
        if(i<=mid) ans=Math.min(ans,query(i,j,st,mid,p<<1));
        if(j>mid) ans=Math.min(ans,query(i,j,mid+1,ed,p<<1|1));
        return ans;
    }
    void pushUp(int p){
        min[p]=Math.min(min[p<<1],min[p<<1|1]);
    }
    void pushDown(int p){
        if(lazy[p]==INF) return;
        min[p<<1]=Math.min(min[p<<1],lazy[p]);
        min[p<<1|1]=Math.min(min[p<<1|1],lazy[p]);
        lazy[p<<1]=Math.min(lazy[p<<1],lazy[p]);
        lazy[p<<1|1]=Math.min(lazy[p<<1|1],lazy[p]);
        lazy[p]=INF;
    }
}

标签:学习指南,return,int,线段,tree,mid,st,高阶,ll
From: https://www.cnblogs.com/taotao123456/p/17763657.html

相关文章

  • 线段树合并
    P4556[Vani有约会]雨天的尾巴/【模板】线段树合并有\(n(n≤10^5)\)个点,形成树状结构。有\(m(m≤10^5)\)次发放操作,每次选择两个点\(x,y\),对\(x\)到\(y\)的路径上(包括\(x,y\))的每个点发放一个\(z(z≤10^5)\)类型的物品。求完成所有操作后,每个点存放最多的是哪种......
  • Ubunte技术学习指南
    安装gcc并检测终端命令sudoaptinstallgccgcc--version//查看版本号,检测是否正确安装创建.c文件touchtest.cvimtest.c//进入vim,进行编程序,退出:进入命令指令系统,:wqgcctest.c//生成a.out./a.out//运行c语言程序......
  • 一道有趣的线段树题目
    \(T4\)莫队首先我们需要知道一种统计答案的方法。我们记\(R_i\)表示右边第一个和他相同的位置。那么我们记\(a_i=\min(a_{i+1},R_i)\),那么贡献就是\(a_i-i+1\),所以我们最后就是要维护\(a_i\)就好了。但是实际上如果你要直接维护\(a_i\)没有任何性质是做不了的。......
  • 谈谈"求线段交点"的几种算法(js实现,完整版)
    谈谈"求线段交点"的几种算法(js实现,完整版)"求线段交点"是一种非常基础的几何计算,在很多游戏中都会被使用到. 下面我就现学现卖的把最近才学会的一些"求线段交点"的算法说一说,希望对大家有所帮助. 本文讲的内容都很初级,主要是面向和我一样的初学者,所以请各位算法帝......
  • 《MySQL与MariaDB学习指南》高清高质量 原版电子书PDF+源码
    下载:https://pan.quark.cn/s/2392eb287424......
  • Go函数全景:从基础到高阶的深度探索
    在本篇文章中,我们深入探索了Go语言中的函数特性。从基础的函数定义到特殊函数类型,再到高阶函数的使用和函数调用的优化,每一个部分都揭示了Go的设计哲学和其对编程效率的追求。通过详细的代码示例和专业解析,读者不仅可以掌握函数的核心概念,还能了解如何在实践中有效利用这些特性来......
  • [完结16章]React18内核探秘:手写React高质量源码迈向高阶开发
    点击下载——[完结16章]React18内核探秘:手写React高质量源码迈向高阶开发  提取码:8epr手写React高质量源码,迈向高阶开发React18内核探秘:手写React高质量源码迈向高阶开发batching批处理,说的是,可以将回调函数中多个setState事件合并为一次渲染,因此是异步的。解决的问题是......
  • [Резюме] 广义李超线段树
    前言“李超线段树,简称李超树。它支持插入直线或线段,并查询某个横坐标处的最值。”本文以最大值为例,讨论广义李超线段树,与传统的李超线段树不同,它插入的是函数而非直线或线段,但为了保证正确的时间复杂度,对函数有较严格限制,见条件。不展开讨论对于\(x=k\)时函数值相等时......
  • GO数组解密:从基础到高阶全解
    在本文中,我们深入探讨了Go语言中数组的各个方面。从基础概念、常规操作,到高级技巧和特殊操作,我们通过清晰的解释和具体的Go代码示例为读者提供了全面的指南。无论您是初学者还是经验丰富的开发者,这篇文章都将助您更深入地理解和掌握Go数组的实际应用。关注公众号【TechLeadClou......
  • GO数组解密:从基础到高阶全解
    在本文中,我们深入探讨了Go语言中数组的各个方面。从基础概念、常规操作,到高级技巧和特殊操作,我们通过清晰的解释和具体的Go代码示例为读者提供了全面的指南。无论您是初学者还是经验丰富的开发者,这篇文章都将助您更深入地理解和掌握Go数组的实际应用。关注公众号【TechLeadClo......