可持久化数据结构学习笔记

可持久化数组

例题

可持久化线段树

算法流程

复杂度分析

例题

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9;
int a[N], b[N], root[N], cnt, n, m;
struct{
	int L, R, sum;
} tree[N << 5];
int build(int pl, int pr){
	int rt = ++cnt;
	tree[rt].sum = 0;
	int mid = (pl + pr) >> 1;
	if(pl < pr){
		tree[rt].L = build(pl, mid);
		tree[rt].R = build(mid + 1, pr);
	}
	return rt;
}
int modify(int pre, int pl, int pr, int x){
	int rt = ++cnt;
	tree[rt].L = tree[pre].L;
	tree[rt].R = tree[pre].R;
	tree[rt].sum = tree[pre].sum + 1;
	int mid = (pl + pr) >> 1;
	if(pl < pr){
		if(x <= mid)
			tree[rt].L = modify(tree[pre].L, pl, mid, x);
		else
			tree[rt].R = modify(tree[pre].R, mid + 1, pr, x);
	}
	return rt;
}
int query(int u, int v, int pl, int pr, int k){
	if(pl == pr)
		return pl;
	int x = tree[tree[v].L].sum - tree[tree[u].L].sum;
	int mid = (pl + pr) >> 1;
	if(x >= k)
		return query(tree[u].L, tree[v].L, pl, mid, k);
	else
		return query(tree[u].R, tree[v].R, mid + 1, pr, k - x);
}
int main(){
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i++){
		scanf("%d", &a[i]);
		b[i] = a[i];
	}
	sort(b + 1, b + n + 1);
	int size = unique(b + 1, b + n + 1) - (b + 1);
	for(int i = 1; i <= n; i++){
		int x = lower_bound(b + 1, b + size + 1, a[i]) - b;
		root[i] = modify(root[i - 1], 1, size, x);
	}
	while(m--){
		int x, y, k;
		scanf("%d%d%d", &x, &y, &k);
		printf("%d\n", b[query(root[x - 1], root[y], 1, size, k)]);
	}
	return 0;
}

可持久化平衡树

可持久化并查集

可持久化可并堆

posted @   JPGOJCZX  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示