P3834 【模板】可持久化线段树 2

先用结构体实现了下,发现写错了(只有20分),后面直接用的数组了


#include<bits/stdc++.h>
using namespace std;

const int N = 2e5 + 7;

int a[N], hs[N], rt[N], cnt;
struct Node{
	int l, r, sum;
}tree[N * 60];

int build(int l, int r){
	int p = ++ cnt;
	tree[p].sum = 0;
	if(l == r)
		return p;
	int mid = (l + r) >> 1;
	tree[p].l = build(l, mid);
	tree[p].r = build(mid+1, r);
	return p;
}

int addtree(int l, int r, int node, int val){
	int p = ++cnt;
	tree[p].l = tree[node].l, tree[p].r = tree[node].r;
	tree[p].sum = tree[node].sum + 1;
	if(l == r)
		return p;
	int mid = (l + r) >> 1;
	if(val <= mid) tree[p].l = addtree(l, mid, tree[node].l, val);
	else tree[p].r = addtree(mid + 1, r, tree[node].r, val);
	return p;
}

int query(int l, int r, int y, int x, int k){
	int suml = tree[tree[x].l].sum - tree[tree[y].l].sum;
	if(l == r)
		return hs[l];
	int mid = (l + r) >> 1;
	if(suml >= k) return query(l, mid, tree[y].l, tree[x].l, k);
	else return query(mid + 1, r, tree[y].r, tree[x].r, k - suml);
}

int main(){
	int n, q;
	scanf("%d%d", &n, &q);
	for(int i = 1;i <= n;i ++) scanf("%d", &a[i]), hs[i] = a[i];
//	cout << endl << endl << endl;
//	for(int i = 1;i <= n;i ++) cout << a[i] << "  ";
	sort(hs+1, hs+n+1);
	int t = unique(hs+1, hs+n+1) - hs - 1;
	rt[0] = build(1, t);
	for(int i=1; i<=n; i++){
		int p = lower_bound(hs+1, hs+t+1, a[i]) - hs;
		rt[i] = addtree(1, t, rt[i - 1], p);
	}
	while(q --){
		int l, r, k;
		scanf("%d%d%d", &l, &r, &k);
		printf("%d\n", query(1, t, rt[l - 1], rt[r], k));
	}
	return 0;
}
posted @   feuerwerk  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示