首页 > 其他分享 >线段树

线段树

时间:2024-02-20 19:35:04浏览次数:23  
标签:rt val int 线段 tree mid

线段树是一种基于分治思想的二叉树结构,用于在区间上进行信息统计。

  1. 线段树的每个节点都代表一个区间
  2. 线段树具有唯一的根节点,代表的区间是整个统计范围,如[1,n]
  3. 线段树的每个叶节点都代表一个长度为1的元区间
  4. 对于每个内部节点[l,r],它的左子节点是[l,mid],右子节点是[mid+1,r],其中mid=(l+r)>>1

线段树的建树

void build(int rt,int l,int r){
	tree[rt].l=l;
	tree[rt].r=r;
	if(l==r){
		tree[rt].sum=tree[rt].max=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	tree[rt].sum=tree[lson].sum+tree[rson].sum;
	tree[rt].max=max(tree[lson].max,tree[rson].max);
}
    build(1,1,n);//调用入口

线段树的单点修改

void update(int rt,int pos,int val){
	if(tree[rt].l==tree[rt].r){
		tree[rt].sum+=val;
		tree[rt].max=val;
		return;
	}
	int mid=(tree[rt].l+tree[rt].r)>>1;
	if(pos<=mid) update(lson,pos,val);
	else update(rson,pos,val);
	tree[rt].sum=tree[lson].sum+tree[rson].sum;
	tree[rt].max=max(tree[lson].max,tree[rson].max);
}
update(1,pos,val);//调用入口

线段树的区间查询

int query(int rt,int l,int r){
	if(tree[rt].l > r or tree[rt].r < l) return 0;
	if(l<=tree[rt].l&&tree[rt].r<=r) return tree[rt].sum;
	int mid=(tree[rt].l+tree[rt].r)>>1;
	int val=0;
	if(l<=mid) val+=Query(lson,l,r);
	if(r>mid) val+=Query(rson,l,r);
	return val; 
}
cout<<query(1,l,r)<<endl;//调用入口

 

标签:rt,val,int,线段,tree,mid
From: https://www.cnblogs.com/yht8866/p/18023880

相关文章

  • 线段树—模板
    线段树常见操作build建树update更新query查询pushup向上回溯pushdown向下延迟更新(延迟标记)建线段树://预编译命令,做符号代换#definelson(gjd<<1)#definerson(gjd<<1|1)//gjd表示当前结点,[l,r]表示区间范围voidbuild(intgjd,intl,intr){tree[gjd]......
  • [COGS 755]山海经:线段树
    这是一道美妙的线段树板子,能够有效地提升我们的读题,理解,思考和代码能力;综上,这是一道大模拟显然,对于这道题的数据范围,直接暴力是行不通的,只能拿30分:30分暴力#include<bits/stdc++.h>usingnamespacestd;constintN=1000005;constintinf=0x7fffffff;structtree{ int......
  • 三哼经(山海经) 线段树
    关于这道题,网上的题解基本都是什么求最大连续子段和,还有什么最大前缀、最大后缀,看了半天也是实在看不明白,便找了个题解,开始给题解写注释(众所周知题解里基本没有注释doge),写了一下午加一晚上,倒是差不多明白了,又肝了0.3坤天终于把三哼经拿下了。题目巴拉巴拉说了一堆没用的的话,让......
  • 线段树-山海经 题解
    《最痛苦的一集》从开始的找维护变量到依据i比较依据y比较最后发现问题出在没初始化(如果不将答案赋值为极小值那么它最小值就是0因此wa了无数遍下面是思路首先要维护的变量有:\(区间的左右边界\,l,\,r\)\(区间的答案\,ans\)\(含左端点最大值\,lans\,和含右端点最......
  • 线段树
    线段树算是树状数组的进阶版了,树状数组能做的,线段树也肯定能做,它做不了的,线段树也能做。但确实线段树的代码量也很让人挠头,基本原理不再解释。先看一下基础的模板吧单点修改和区间查询点击查看代码#include<bits/stdc++.h>usingnamespacestd;constintN=300000;intn......
  • "山海经“ 讲解----线段树
    ”山海经“--线段树讲解1、题面:http://cogs.pro/cogs/problem/problem.php?pid=7752、题目大意及分析:i:大概就是说给了你一段[1,n]的区间,并给了每个区间的权值,下面会有m个问题,每个问题给你一段[1,n]的子区间[i,j],问你在这段区间上的任意一端子区间和最大是多少,并且要求输出这......
  • 线段树的各种板板~(*^▽^*)
    $\color{purple}{板板}$#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong#defineinf0x3f#defineINF0x3f3f3f3f#definemst(a,b)memset(a,b,sizeof(a))#defineElaina0#definelid(id<<1)#definerid(id<<1|1)//即ridco......
  • 线段树模板
    开局宏定义:#include<bits/stdc++.h>#defineintlonglong#definelson(now<<1)//现结点的左孩子#definerson(now<<1|1)//右孩子usingnamespacestd;结构体定义:structNode{intl,r;//表示左右区间intmax,sum;//其他数据域}tree[N<<2]//=N*......
  • 线段树(板子)
    线段树单点修改,单点,区间查询区间修改,单点,区间查询单点修改普通线段树code#definels(rt<<1)#definers(rt<<1|1)#definellllonglongconstintN=1000001;intn,m;inta[N];structT{ intl,r,data;}tr[N<<2];voidpushup(intrt){ tr[rt].da......
  • 线段树-基础模版
    线段树模版一埋头扎进线段树一上午感觉很神奇几个函数就能把它完整的复现下来这里有几张基础概念的图对着代码来想还是很好理解的最后是整理了能够处理总和最大值和最小值的线段树模版code:$\LARGE\color{purple}{代码在这里}$#include<bits/stdc++.h>usingnames......