首页 > 其他分享 >【学习笔记】线段树

【学习笔记】线段树

时间:2024-01-29 11:11:20浏览次数:34  
标签:rs int 线段 笔记 学习 ls sm sg

1.线段树合并

P4556 雨天的尾巴

首先我们可以把链上操作转成树上差分。然后我们对每个节点开一棵权值线段树。朴素的树上差分都是开一个桶然后加和,但是这里开的是线段树。

所以就有了线段树合并。

在把 \(y\) 并到 \(x\) 的过程中,如果 \(x\) 本身没有一个 \(y\) 有的节点就可以直接把 \(y\) 的那个节点接上去节省时间。

就没了。

inline void merge(int x,int y){
	if(!sg[x].ls&&!sg[x].rs&&!sg[y].ls&&!sg[y].rs){//并到叶子节点了直接两个合起来
		sg[x].sm+=sg[y].sm;
		return;
	}
	if(sg[y].ls){//如果要并过来的没有左儿子就不用往左边合并了
		if(sg[x].ls)merge(sg[x].ls,sg[y].ls);
		else sg[x].ls=sg[y].ls;
	}
	if(sg[y].rs){
		if(sg[x].rs)merge(sg[x].rs,sg[y].rs);
		else sg[x].rs=sg[y].rs;
	}
	sg[x].sm=sg[sg[x].ls].sm+sg[sg[x].rs].sm;//更新
	return;
}

首先很容易看得出来单次合并的复杂度是 \(O(重合大小)\) 的。

那么对于 \(n\) 棵最开始只有一个元素的线段树,合并起来的复杂度是 \(O(n\log n)\)。这个很显然,因为就算所有元素都相等每次都跑满也只有 \(\log n\) 次。

注意线段树合并只能用于动态开点,因为普通线段树本来就是满的。

开个坑。

首先有朴素 dp:令 \(dp_{i,j}\) 表示节点 \(i\) 取到 \(j\) 的概率。假设这个值从左儿子传过来(右儿子同理),那么转移方程是 \(dp_{i,j}=dp_{ls,j}\times(p_i\times\sum_{k=1}^{j}dp_{rs,k}+(1-p_i)\times\sum_{k=j}^{n}dp_{rs,k})\)。

我们可以考虑用线段树合并。

2. 线段树分裂

P5494 【模板】线段树分裂

在分裂函数里面传当前节点,就是一边分裂一边建树。复杂度和区间查询一样。

inline void split(int ql,int qr,int &x,int &y,int l,int r){
	if(!x||qr<l||r<ql)return;
	if(ql<=l&&r<=qr){//就是要割的
		y=x;
		x=0;
		return;
	}
	if(!y)y=build();
	int mid=(l+r)>>1;
	if(ql<=mid)split(ql,qr,sg[x].ls,sg[y].ls,l,mid);
	if(qr>mid)split(ql,qr,sg[x].rs,sg[y].rs,mid+1,r);
	sg[x].sm=sg[sg[x].ls].sm+sg[sg[x].rs].sm;
	sg[y].sm=sg[sg[y].ls].sm+sg[sg[y].rs].sm;
	return;
}

标签:rs,int,线段,笔记,学习,ls,sm,sg
From: https://www.cnblogs.com/Zsq20100122/p/17993757

相关文章

  • 浮木云学习日志(5)---APP页面搭建
    上次分享了浮木云的交互编排,帮助我们实现了页面一些简单交互操作,而这些简单的交互操作已经基本能够覆盖完整的页面交互了。剩下一些复杂的交互编排我准备在后续用到的过程中再给大家一一分享。今天我准备进军APP端静态页面搭建了,可能我这人对任何事都充满好奇,在看到浮木云可以直......
  • 寒假学习日志2-spark的安装和配置
    1.在官网下载spark(需要在hadoop安装配置完成后进行)下载的是2.4.0版本的2.将压缩文件放入到linux系统中进行解压 3.安装后,还需要修改Spark的配置文件spark-env.sh 4.验证spark的安装  安装成功5.使用spark-shell ......
  • 算法笔记 pdf下载
    《算法笔记》内容包括:C/C++快速入门、入门模拟、算法初步、数学问题、C++标准模板库(STL)、数据结构专题(二章)、搜索专题、图算法专题、动态规划专题、字符串专题、专题扩展。《算法笔记》印有二维码,用来实时更新、补充内容及发布勘误的。《算法笔记》可作为计算机专业研究生入学考......
  • [转帖]Oracle SQL调优系列之cursor学习笔记
    https://cloud.tencent.com/developer/article/1995387 文章目录-[一、oracle库缓存](https://cloud.tencent.com/developer)-[1.1、库缓存简介](https://cloud.tencent.com/developer)-[1.2、相关概念](https://cloud.tencent.com/developer)......
  • WebAssembly入门笔记[3]:利用Table传递引用
    在《WebAssembly入门笔记[2]》中,我们介绍了如何利用Memory在作为宿主的JavaScript应用和wasm模块之间传递数据,但是Memory面向单纯二进制字节的读写在使用起来还是不太方便,此时我们会更多地用到另一个重要的对象Table。Table利用用来存储一组指定类型的对象,说得准确一点是对象的引......
  • sql注入学习
    SQL注入分类SQL注入按照类型分为数字型注入和字符型注入。注入点的数据类型为数字型时为数字型注入,注入点的数据类型为字符型为字符型注入。SQL注入按照服务器返回信息是否显示分为报错注入和盲注。如果在注入的过程中,程序将获取的信息或者报错信息直接显示在页面中,这样的注入为......
  • Python 基于pymongo操作Mongodb学习总结
    实践环境Python3.6.4pymongo4.1.1pymongo-3.12.3-cp36-cp36m-win_amd64.whl下载地址:https://pypi.org/simple/pymongo/代码实践#!/usr/bin/envpython#-*-coding:utf-8-*-importdatetimeimportrandomimportpymongofrompymongoimportMongoClientfrombson.......
  • 数学建模入门笔记(3) 插值与拟合
    插值与拟合插值和拟合的区别:拟合不要求过每一个已知点,而插值要求过每一个已知点,因而插值可以看作过每一个点的拟合。插值适用于补全缺失值,因为使用一般拟合就有可能使已知值偏移,不符合需求。据说PS用某种样条插值,放大的时候最大程度的保留连续性,因此显得不是那么模糊.数学建模......
  • Rust学习笔记
    迭代器迭代器是一个值,它可以生成一系列值Iterrator类型和IntoIterator类型迭代器是实现了Iterator类型的任意值IntoIterator是迭代器本身类型,Item是它生成的值的类型。任意实现了IntoIterator的类型都可以成为可迭代者,可以通过into_iter获得一个迭代器迭代器能生成值迭......
  • 学习笔记推荐:极客时间《Java常见错误100例》
    最近,我有幸接触了一套非常精彩的学习笔记,《Java常见错误100例》。(手册链接在文末!!!)这套学习笔记出自极客时间,对于想要在Java开发领域深耕细作的朋友们来说,它无疑是一个不可多得的宝藏。接下来,我将结合其内容目录中的一些亮点,为大家进行简要介绍。首先,这套学习笔记囊括了Java......