「Note」数据结构方向 - 可持久化数据结构
1. 可持久化线段树
1.1. 简介
可持久化线段树一般用于解决区间第 \(k\) 小值的询问。
首先考虑简化过的问题,区间 \(\left[1,r\right]\) 的第 \(k\) 小值。
考虑用权值线段树(离散化或动态开点)来求 \(k\) 小值,接下来只需要解决区间的问题。
可持久化线段树核心思想:每次插入值时保留历史版本,来实现区间查询第 \(k\) 小。若每次修改暴力地复制一颗线段树显著不可行,考虑到每次修改最多影响 \(\log n\) 级别个数的节点,我们将这些受影响的节点分离出来进行建树,如下图(源于 OI-wiki)。
我们按顺序一个一个插入值,对于区间 \(\left[1,r\right]\) 的第 \(k\) 小值,只需要访问插入第 \(r\) 个值后的那个版本即可。
至于区间 \(\left[l,r\right]\) 的第 \(k\) 小值,只需要使用区间 \(\left[1,r\right]\) 的信息减去区间 \(\left[1,l-1\right]\) 的信息便可求出。
1.2. 例题
\(\color{royalblue}{P3834}\)
板子。
$\text{Code}$:
```
#include
#define LL long long
#define UN unsigned
using namespace std;
//--------------------//
//IO
inline int rd()
{
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
//--------------------//
const int N=2e5+5;
int n,m;
int s[N];
int tcnt,tem[N],id[N];
//--------------------//
const int TN=64e5+5;
struct Seg_Tree
{
struct Seg_Tree_Node
{
int ls,rs;
int val;
}t[TN];
int root[N],tot=0;
void build(int &rt,int L,int R)
{
rt=++tot;
if(LR)
return;
int mid=L+R>>1;
build(t[rt].ls,L,mid);
build(t[rt].rs,mid+1,R);
return;
}
void change(int &rt,int lst,int L,int R,int pos)
{
rt=++tot;
t[rt]=t[lst];
t[rt].val++;
int mid=L+R>>1;
if(LR)
return;
if(pos<=mid)
change(t[rt].ls,t[lst].ls,L,mid,pos);
else
change(t[rt].rs,t[lst].rs,mid+1,R,pos);
return;
}
int query(int rt,int pre,int L,int R,int rk)
{
if(L==R)
return L;
int mid=L+R>>1;
if(rk<=t[t[rt].ls].val-t[t[pre].ls].val)
return query(t[rt].ls,t[pre].ls,L,mid,rk);
return query(t[rt].rs,t[pre].rs,mid+1,R,rk-(t[t[rt].ls].val-t[t[pre].ls].val));
}
}T;
//--------------------//
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&s[i]),tem[++tcnt]=s[i];
sort(tem+1,tem+tcnt+1);
tcnt=unique(tem+1,tem+tcnt+1)-tem-1;
T.build(T.root[0],1,tcnt);
for(int temp,i=1;i<=n;i++)
{
temp=lower_bound(tem+1,tem+tcnt+1,s[i])-tem;
id[temp]=s[i];
s[i]=temp;
T.change(T.root[i],T.root[i-1],1,tcnt,s[i]);
}
for(int l,r,rk,i=1;i<=m;i++)
{
scanf("%d%d%d",&l,&r,&rk);
printf("%d\n",id[T.query(T.root[r],T.root[l-1],1,tcnt,rk)]);
}
return 0;
}
</details>
「Note」数据结构方向 - 可持久化数据结构的更多相关文章
- 「NOTE」常系数齐次线性递推
要不是考到了,我还没发现这玩意我不是很会-- # 前置 多项式取模: 矩阵快速幂. # 常系数齐次线性递推 描述的是这么一个问题,给定数列 \(c_1,c_2,\dots,c_k\) 以及数列 \(f ...
- LOJ #2718. 「NOI2018」归程 Dijkstra+可持久化并查集
把 $Noi2018$ day1t1 想出来还是挺开心的,虽然是一道水题~ 预处理出来 1 号点到其它点的最短路,然后预处理边权从大到小排序后加入前 $i$ 个边的并查集. 这个并查集用可持久化线段树 ...
- 「HNOI2016」数据结构大毒瘤
真是 \(6\) 道数据结构毒瘤... 开始口胡各种做法... 「HNOI2016」网络 整体二分+树状数组. 开始想了一个大常数 \(O(n\log^2 n)\) 做法,然后就被卡掉了... 发现直 ...
- 「luogu3402」【模板】可持久化并查集
「luogu3402」[模板]可持久化并查集 传送门 我们可以用一个可持久化数组来存每个节点的父亲. 单点信息更新和查询就用主席树多花 一个 \(\log\) 的代价来搞. 然后考虑如何合并两个点. ...
- Note -「多项式」基础模板(FFT/NTT/多模 NTT)光速入门
进阶篇戳这里. 目录 何为「多项式」 基本概念 系数表示法 & 点值表示法 傅里叶(Fourier)变换 概述 前置知识 - 复数 单位根 快速傅里叶正变换(FFT) 快速傅里叶逆变换(I ...
- 「SOL」JOISC2021 解题报告
JOIS(egment-Tree)C 1. 前言 很早之前教练让我们做这套题,我以为这套题应该挺简单,用几天的空余时间就能刷完,结果预想的短周期刷题变成了长周期刷题--(好像是整个团队里最后一个刷完的 ...
- LOJ #2135. 「ZJOI2015」幻想乡战略游戏(点分树)
题意 给你一颗 \(n\) 个点的树,每个点的度数不超过 \(20\) ,有 \(q\) 次修改点权的操作. 需要动态维护带权重心,也就是找到一个点 \(v\) 使得 \(\displaystyle ...
- Loj #3055. 「HNOI2019」JOJO
Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...
- 「MoreThanJava」当大学选择了计算机之后应该知道的
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
- 《Offer一箩筐》一份高质量「简历」撰写指南,望打扰!!
「MoreThanJava」 宣扬的是 「学习,不止 CODE」. 如果觉得 「不错」 的朋友,欢迎 「关注 + 留言 + 分享」,文末有完整的获取链接,您的支持是我前进的最大的动力! Hi~ 这里是 ...
随机推荐
- 依赖注入(DI)与控制反转(IoC)
.wj_nav { display: inline-block; width: 100%; margin-bottom: 0.375rem } .wj_nav span { display: inli ...
- linux ln命令详解
介绍 ln是linux的一个重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接.当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在 ...
- Win10下子系统Unbuntu18.04安装nginx
1.Nginx的软件包在Ubuntu默认软件仓库中可用. 安装非常简单,只需键入以下命令: sudo apt update sudo apt install nginx 2.安装完成后,检查Nginx ...
- go 组合函数 Collection
我们经常需要程序在数据集上执行操作,比如选择满足给定条件的所有项,或者将所有的项通过一个自定义函数映射到一个新的集合上. 在某些语言中,会习惯使用泛型. Go 不支持泛型,在 Go 中,当你的程序或者 ...
- PaddleOCR学习笔记3-通用识别服务
今天优化了下之前的初步识别服务的python代码和html代码. 采用flask + paddleocr+ bootstrap快速搭建OCR识别服务. 代码结构如下: 模板页面代码文件如下: uplo ...
- swich语句
1.switch语句格式 括号内的是待匹配内容,然后case后的是被匹配内容,如果括号内的内容与case后的内容一致,则会打印语句体 . 2.实操(后面的省略了) 3.注意事项 1.case后面的值不 ...
- 【Linux】3.4 用户管理
用户管理 1. 基本用户管理 Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统. 用户的账号一方面可以帮助 ...
- golang的条件编译
写c/c++或者rust的开发者应该对条件编译不陌生,条件编译顾名思义就是在编译时让代码中的一部分生效或者失效,从而控制编译时的代码执行路径,进而影响编译出来的程序的行为. 这有啥用呢?通常在编写跨平 ...
- soapUI参数化总结
1.新建项目目录 以获取用户贡献等级为例,目录如下: 2.添加DataSource和DataSource Loop 选中Test Step右键分别新建DataSource和DataSource Loo ...
- Postman接口关联总结
1.新建集合 打开postman,点击Collections->New Collection,页面如下: 2.新建请求 下面以获取绑定信息接口为例 接口说明: C{获取绑定信息接口} 接口地址: ...