可持久化线段树学习笔记

模板

#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;
}

可持久化线段树

共用节点的n棵线段树。
可持久化权值线段树也称主席树

例题

好了,你现在已经学会主席树的全部内容)),让我们来口胡几道简单题吧。

题目链接:区间第k大
全局想必大家都会,权值线段树的板子。
当询问区间的时候,
我们建立n棵权值线段树,第i棵表示1~i的权值线段树。
利用前缀和的思想,用第r棵减去第l-1棵便能求出l~r的权值情况。
所以我们直接建主席树来表示这n棵线段树就好了。

题目链接:[POI2014]KUR-Couriers
把上一题求答案的函数改改就行。

题目链接:Dynamic Rankings
带修改的第k大,在静态第k大中的主席树外套个树状数组即可。
平衡树套线段树也行。

题目链接:Count on a tree
树上第k大。
注意的两个点:

  1. 结点u应该在fau的基础上建树。
  2. lca求距离时是这样的:disu+disv2×dislcau,v,这个题应该是disu+disv dislcau,v disfalcau,v


题目链接:Middle
不错的题目,不是建权值线段树了,Middle题解

题目链接:[SDOI2013]森林
树上第k大加启发式合并。

题目链接:CF840D Destiny
luogu上黑了。。其实是个sb题。

题目链接:[CQOI2015]任务查询系统
差分一发,然后统计前缀和,线段树合并就好了。

题目链接:[NOI2010] 超级钢琴
先求前缀和。
因为子段长度有LR的限制,如果固定左端点L,右端点R就在一段固定的区间里选择。
要使sumRsumL最大,那么sumR就应该尽量大。
有个很常见的二叉堆贪心技巧,就是下面的做法:

  1. 建立一个大根堆,以val为指标,每个元素是一个三元组(L,c,val)表示以L为左端点选到了第c大的右端点,子段值为val
  2. 先插入每个(i,1,val)
  3. 每次取出堆顶,加上它的val,然后通过L查询选定区间第k+1大的val,然后插入(L,c+1,val),很显然可以主席树。
  4. 执行第3个步骤k次。输出结果。
posted @   Isenthalpic  阅读(61)  评论(0编辑  收藏  举报
编辑推荐:
· 从 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的设计差异
点击右上角即可分享
微信分享提示