📚【模板】主席树

1.区间第k小

#include <stdio.h>
#include <string.h>
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
using namespace std;
const int N = 524288;
int a[N], b[N], root[N];
int n, m, boarder;

struct TSEG {
	int lid, rid;
	int sum;
} tseg[N<<6];
int tot;
#define lid(id) tseg[id].lid
#define rid(id) tseg[id].rid
#define sum(id) tseg[id].sum
int construct(int L,int R) {
	int id = ++tot;
	if(L == R) return id;
	int mid = (L+R)>>1;
	lid(id) = construct(L,mid);
	rid(id) = construct(mid+1,R);
	return id;
}
int insert(int id,int L,int R,int val) {
	int nts = ++tot;//New TSeg node;
	lid(nts) = lid(id);
	rid(nts) = rid(id);
	sum(nts) = sum(id)+1;
	if(L == R) 
		return nts;
	int mid = (L+R)>>1;
	if(val <= mid) 
		lid(nts) = insert(lid(nts),L,mid,val);
	else 
		rid(nts) = insert(rid(nts),mid+1,R,val);
	return nts;
}
int query(int uid,int vid,int L,int R,int k) {
	int mid = (L+R)>>1;
	int del = sum(lid(vid))-sum(lid(uid));
	if(L == R) return L;
	if(k <= del) 
		return query(lid(uid),lid(vid),L,mid,k);
	else 
		return query(rid(uid),rid(vid),mid+1,R,k-del);
}

int getrank(int val) {
	return lower_bound(b+1,b+boarder+1,val)-b;
}

signed main() {
	scanf("%d %d",&n,&m);
	for(int i = 1;i <= n;++i) 
		scanf("%d",&a[i]);
	memcpy(b,a,(n+1)*sizeof(int));
	sort(b+1,b+n+1);
	boarder = unique(b+1,b+n+1)-b-1;
	root[0] = construct(1,boarder);
	for(int i = 1;i <= n;++i) 
		root[i] = insert(root[i-1],1,boarder,getrank(a[i]));
	for(int i = 1, l, r, k;i <= m;++i) {
		scanf("%d %d %d",&l,&r,&k);
		printf("%d\n",b[query(root[l-1],root[r],1,boarder,k)]);
	}
}

2.可持久化数组

#include <stdio.h>
#include <string.h>
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
using namespace std;
const int N = 1048576;
int a[N], root[N];
int n, m, boarder;

struct TSEG {
	int lid, rid;
	int val;
} tseg[N<<6];
int tot;
#define lid(id) tseg[id].lid
#define rid(id) tseg[id].rid
#define val(id) tseg[id].val
int construct(int L,int R) {
	if(L > R) return 0;
	int id = ++tot;
	int mid = (L+R)>>1;
	val(id) = a[mid];
	if(L == R) return id;
	lid(id) = construct(L,mid-1);
	rid(id) = construct(mid+1,R);
	return id;
}
int insert(int id,int L,int R,int pos,int v) {
	int nts = ++tot;
	lid(nts) = lid(id);
	rid(nts) = rid(id);
	val(nts) = val(id);
	int mid = (L+R)>>1;
	if(pos == mid) 
		val(nts) = v;
	else if(pos < mid) 
		lid(nts) = insert(lid(nts),L,mid-1,pos,v);
	else 
		rid(nts) = insert(rid(nts),mid+1,R,pos,v);
	return nts;
}
int query(int id,int L,int R,int pos) {
	int mid = (L+R)>>1;
	if(mid == pos) 
		return val(id);
	else if(pos < mid) 
		return query(lid(id),L,mid-1,pos);
	else
		return query(rid(id),mid+1,R,pos);
}

signed main() {
	scanf("%d %d",&n,&m);
	for(int i = 1;i <= n;++i) 
		scanf("%d",&a[i]);
	root[0] = construct(1,n);
	for(int i = 1, ver, opt, p, v;i <= m;++i) {
		scanf("%d %d %d",&ver,&opt,&p);
		if(opt == 1) {
			scanf("%d",&v);
			root[i] = insert(root[ver],1,n,p,v);
		} else {
			printf("%d\n",query(root[ver],1,n,p));
			root[i] = root[ver];
		}
	}
}
posted @ 2022-07-26 12:04  bikuhiku  阅读(14)  评论(0编辑  收藏  举报