可持久化线段树学习笔记
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int cnt,rt[N];
int n,a[N],t[N],T;
int ls[N*20],rs[N*20],dat[N*20];
void Copy(int x,int y){
ls[x]=ls[y];
rs[x]=rs[y];
dat[x]=dat[y]+1;
return;
}
int build(int l,int r){
int p=++cnt;
if(l==r)return p;
int mid=l+r>>1;
ls[p]=build(l,mid);
rs[p]=build(mid+1,r);
return p;
}
int insert(int pre,int l,int r,int x){
int p=++cnt;
Copy(p,pre);
if(l==r)return p;
int mid=l+r>>1;
if(x<=mid)ls[p]=insert(ls[pre],l,mid,x);
else rs[p]=insert(rs[pre],mid+1,r,x);
return p;
}
int query(int p,int q,int l,int r,int k){
if(l==r)return l;
int nc=dat[ls[q]]-dat[ls[p]],ret;
int mid=l+r>>1;
if(nc>=k)ret=query(ls[p],ls[q],l,mid,k);
else ret=query(rs[p],rs[q],mid+1,r,k-nc);
return ret;
}
int main(){
scanf("%d%d",&n,&T);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
t[i]=a[i];
}
sort(t+1,t+n+1);
int m=unique(t+1,t+n+1)-(t+1);
rt[0]=build(1,m);
for(int i=1;i<=n;i++){
int x=lower_bound(t+1,t+m+1,a[i])-t;
rt[i]=insert(rt[i-1],1,m,x);
}
while(T--){
int L,R,K;
scanf("%d%d%d",&L,&R,&K);
printf("%d\n",t[query(rt[L-1],rt[R],1,m,K)]);
}
return 0;
}
可持久化线段树
共用节点的棵线段树。
可持久化权值线段树也称主席树
例题
好了,你现在已经学会主席树的全部内容)),让我们来口胡几道简单题吧。
题目链接:区间第k大
全局想必大家都会,权值线段树的板子。
当询问区间的时候,
我们建立棵权值线段树,第棵表示~的权值线段树。
利用前缀和的思想,用第棵减去第-棵便能求出~的权值情况。
所以我们直接建主席树来表示这棵线段树就好了。
题目链接:[POI2014]KUR-Couriers
把上一题求答案的函数改改就行。
题目链接:Dynamic Rankings
带修改的第大,在静态第大中的主席树外套个树状数组即可。
平衡树套线段树也行。
题目链接:Count on a tree
树上第大。
注意的两个点:
- 结点应该在的基础上建树。
- 求距离时是这样的:,这个题应该是 。
题目链接:Middle
不错的题目,不是建权值线段树了,Middle题解
题目链接:[SDOI2013]森林
树上第大加启发式合并。
题目链接:CF840D Destiny
在上黑了。。其实是个题。
题目链接:[CQOI2015]任务查询系统
差分一发,然后统计前缀和,线段树合并就好了。
题目链接:[NOI2010] 超级钢琴
先求前缀和。
因为子段长度有和的限制,如果固定左端点,右端点就在一段固定的区间里选择。
要使最大,那么就应该尽量大。
有个很常见的二叉堆贪心技巧,就是下面的做法:
- 建立一个大根堆,以为指标,每个元素是一个三元组表示以为左端点选到了第大的右端点,子段值为。
- 先插入每个。
- 每次取出堆顶,加上它的,然后通过查询选定区间第大的,然后插入,很显然可以主席树。
- 执行第个步骤次。输出结果。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异