📚【模板】主席树
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];
}
}
}