可持久化线段树(未完成)

//#include<iostream>
//#include<algorithm>
//
//using namespace std;
//
//const int N=2e5+5;
//struct node{
//	int l,r,cnt;
//};
//node tree[N<<5];
//int tot;
//
//int newnode(int u){
//	tree[++tot]=tree[u];
//	return tot;
//}
//int build(int l,int r){
//	int u=newnode(tot);
//	if(l==r)
//		return u;
//	int mid=(l+r)>>1;
//	tree[u].l=build(l,mid);
//	tree[u].r=build(mid+1,r);
//	return u;
//}
//int modify(int now,int l,int r,int loc){
//	int u=newnode(now);
//	if(l==r)
//		return u;
//	int mid=(l+r)>>1;
//	if(loc<=mid)
//		tree[u].l=modify(tree[now].l,l,mid,loc);
//	else
//		tree[u].r=modify(tree[now].r,mid+1,r,loc);
//	return u;
//}
//int query(int ql,int qr,int l,int r,int k){
//	int cnt=tree[qr].cnt-tree[ql-1].cnt;
//	int mid=(l+r)>>1,res=0;
//	if(k<=cnt)
//		return query(tree[ql].l,tree[qr].l,l,mid,k);
//	else
//		return query(tree[ql].r,tree[qr].r,mid+1,r,k-cnt);
//	return res;
//}
//
//int main(){
//	cin.tie(nullptr)->sync_with_stdio(false);
//	
//}
#include <cstdio>
#include <algorithm>
#define M 200010

using namespace std;

int node_cnt, n, m;
int sum[M<<5], rt[M], lc[M<<5], rc[M<<5];//线段树相关
int a[M], b[M];//原序列和离散序列
int p;//修改点

void build(int &t, int l, int r)
{
	t = ++node_cnt;
	if(l == r)
		return;
	int mid = (l + r) >> 1;
	build(lc[t], l, mid);
	build(rc[t], mid+1, r);
}

int modify(int o, int l, int r)
{
	int oo = ++node_cnt;
	lc[oo] = lc[o]; rc[oo] = rc[o]; sum[oo] = sum[o] + 1;
	if(l == r)
		return oo;
	int mid = (l + r) >> 1;
	if(p <= mid) lc[oo] = modify(lc[oo], l, mid);
	else rc[oo] = modify(rc[oo], mid+1, r);
	return oo;
}

int query(int u, int v, int l, int r, int k)
{
	int ans, mid = ((l + r) >> 1), x = sum[lc[v]] - sum[lc[u]];
	if(l == r)
		return l;
	if(x >= k) ans = query(lc[u], lc[v], l, mid, k);
	else ans = query(rc[u], rc[v], mid+1, r, k-x);
	return ans;
}

int main()
{
	int l, r, k, q, ans;
	scanf("%d%d", &n, &m);
	for(register int i = 1; i <= n; i += 1)
		scanf("%d", &a[i]), b[i] = a[i];
	sort(b+1, b+n+1);
	q = unique(b+1, b+n+1) - b - 1;
	build(rt[0], 1, q);
	for(register int i = 1; i <= n; i += 1)
	{
		p = lower_bound(b+1, b+q+1, a[i])-b;//可以视为查找最小下标的匹配值,核心算法是二分查找
		rt[i] = modify(rt[i-1], 1, q);
	}
	while(m--)
	{
		scanf("%d%d%d", &l, &r, &k);
		ans = query(rt[l-1], rt[r], 1, q, k);
		printf("%d\n", b[ans]);
	}
	return 0;
}

posted on 2026-01-06 21:03  _CENSORED  阅读(15)  评论(0)    收藏  举报

导航