首页 > 其他分享 >关于线段树

关于线段树

时间:2023-10-05 20:13:18浏览次数:26  
标签:rt int 线段 tree vis 关于 define

动态开点

当到了未建立过的新点时再建立点,一般用结构体来存储线段树。

大致代码:

#define lx tree[x].l
#define rx tree[x].r
#define mid ((l + r) >> 1)

int cnt;
struct node{
	int l, r;
	int v;
}tree[N << 5];

inline void pushup(int x){
	tree[x].v = tree[lx].v + tree[rx].v;
}

inline int update(int x, int l, int r, int k, int s){ //此处以单点修改展示
	if(!x) x = ++ cnt;
	
	if(l == r){
	tree[x].v = s;
		return x;
	}
	
	if(k <= mid) tree[x].l = update(lx, l, mid, k);
	if(mid < k) tree[x].r = update(rx, mid + 1, r, k);
	
	pushup(x);
	return x;
}

关于线段树开的空间……
我的评价是:能开大点就开大点,保险

可持久化

常在多颗线段树差异不大但都需访问时使用
即在动态开点上加个记录时间的标记(也可以是其他标记),以达到节省空间开多颗线段树
用 \(rt_i\) 表示第 \(i\) 颗线段树的根节点

注意点:

  1. 一定要先建 \(rt[0]\) 的初始树,即使它可能是颗空树
  2. 开新点的过程大多为直接复制原节点再修改
  3. 相比正常线段树需多用一 \(vis\) 数组来表示该点是否开过
  4. 一定要有回传标号的操作
  5. 可持久化不能使用线段树合并
int rt[N], cnt;
struct node{
	int l, r;
	int v;
	bool vis; //vis 表示当点是否被开过
}tree[N << 5];

inline void pushup(int x){
	tree[x].v = tree[lx].v + tree[rx].v;
}

inline int build(int x, int l, int r){
	x = ++ cnt;
	
	if(l == r){
		return x; //回传标号
	}
	
	tree[x].l = build(lx, l, mid);
	tree[x].r = build(rx, mid + 1, r);
	
	return x; //同上
}

inline int add(int x){
	tree[++ cnt] = tree[x];
	tree[cnt].vis = 1;
	tree[tree[cnt].l].vis = 0;
	tree[tree[cnt].r].vis = 0;
	return cnt;
}

inline int update(int x, int l, int r, int k, int s){
	if(!tree[x].vis){
		x = add(x);
	}
	
	if(l == r){
		tree[x].v = s;
		tree[x].vis = 1;
		return x;
	}
	
	if(k <= mid) tree[x].l = update(lx, l, mid, k, s);
	if(mid < k) tree[x].r = update(rx, mid + 1, r, k, s);
	
	pushup(x);
	return x;
}

int main(){
	rt[0] = build(1, 1, n);
	for(int i = 1; i <= n; ++ i){
		rt[i] = add(rt[i - 1]); //第 i 颗树继承(复制)第 i - 1 颗树
		rt[i] = update(rt[i], 1, n, i, 1);
	}
}

标签:rt,int,线段,tree,vis,关于,define
From: https://www.cnblogs.com/biuld/p/17743208.html

相关文章

  • 关于智能安防及视频监控系统EasyCVR的详细介绍
    安防视频监控平台EasyCVR是一个具有强大拓展性、灵活的视频能力和轻便部署的平台。它支持多种主流标准协议,包括国标GB28181、RTSP/Onvif、RTMP等,还可以支持厂家的私有协议和SDK接入,例如海康Ehome、海大宇等设备的SDK。该平台不仅拥有传统安防视频监控的功能,还具备接入AI智能分析的......
  • 关于一类期望 dp 的公式推导
    想写但想不起来写啥......
  • 线段树学习笔记
    学习链接代码(未完成)#include<bits/std++.h>usingnamespacestd;intarray[200005],tree[200005<<2];//array是初始数组,tree是线段树voidupdate(intitem)//更新item号节点的函数,这里是最大值,也可更改为区间和、最小值等{tree[item]=max(tree[item<<1],tree[it......
  • 有关于Mysql的简单问题及示例(增删改查 一对一 多对多 左外连接 右外链接)
    Mysql1、请自行设计表并针对该表练习最基本的增删改查且写出示例代码建立表格class其中有属性nameidgenderinterest表格建立完成向表中插入数据插入数据完成尝试删除表中id=101的数据删除数据成功尝试修改表中id为102的数据修改成功2、请问什么是一对多?请自......
  • 笔记——线段树
    蓝月の笔记——线段树篇在树状数组中,我们讲解了关于单点修改区间查询的操作。今天,我们要讲一种更加高级的数据结构,他解决的是区间修改区间查询的问题多了一个区间当然更高级啦。这个数据结构就是——线段树Luogu-P3372给定一个长度为\(n\)的序列\(a_1,a_2,\cdots,a_n\)......
  • 关于 Failed to bind properties under 'sky.alioss.access-key-id' to java.lang.Str
    问题描述废话不多说,上截图解决方案问题出现的原因:因为自己没有按照格式去运行程序,在yml中把他们得位置向前一个单位就解决问题了......
  • 关于Async、Await的一些知识点
    在ASP.NETCore中,当一个HTTP请求到达服务器时,它会被分配给线程池中的一个线程来处理。该线程会执行相应的Controller方法。如果这个方法是一个异步方法并且使用了await关键字,那么在await的代码执行完毕之前,这个线程会被释放回线程池,可以用来处理其他的HTTP请求。当await的代码执......
  • 线段树模板
    应该是做的最认真的模板了。。。namespacexds{template<classT,constintMYMAXSIZE,T(*fun)(Ta,Tb)>classSTree{private:Tt[MYMAXSIZE<<2],tag[MYMAXSIZE<<2],a[MYMAXSIZE];intnum;inlineconstintls(constintx){......
  • 【数据结构】- 线段树
    线段树简介线段树是可以维护区间信息的数据结构。线段树将每个长度不为\(1\)的区间划分成左右两个区间递归求解,故把整个线段划分为一个树形结构,通过合并左右两区间信息来求得该区间的信息。根据建树方式可分为普通线段树和动态开点线段树。根据区间信息可分为普通线段树......
  • note 线段树
    适用场景:不断区间修改、区间询问。假设我们要区间求和,\(tree\)的含义:区间的和,其两个子节点为这个区间分为两半的和。我们把一个数组\(a\)看作一颗树\(tree\),例:112333对应的\(tree\)(\(()\)里是编号,\([]\)里是对应的区间):(1)13[1,6]/......