题目链接:【模板】可持久化线段树 1(主席树)
学习链接:主席树
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 10000010;
int n;
int tree[N];
int lt[N], rt[N];
int sum[N];
int totnode;
int a[200010], b[200010];
void build(int &t, int l, int r)
{
t = ++totnode;
if(l == r) return ;
int mid = (l + r) / 2;
build(lt[t], l, mid);
build(rt[t], mid + 1, r);
}
int update(int o, int l, int r, int pos)
{
int oo = ++totnode;
lt[oo] = lt[o];
rt[oo] = rt[o];
sum[oo] = sum[o] + 1;
if(l >= r) return oo;
int mid = (l + r) / 2;
if(pos <= mid) lt[oo] = update(lt[oo], l, mid, pos);
else rt[oo] = update(rt[oo], mid + 1, r, pos);
return oo;
}
int query(int u, int v, int l, int r, int key)
{
int now = sum[lt[v]] - sum[lt[u]];
if(l == r) return l;
int mid = (l + r) / 2;
if(now >= key) return query(lt[u], lt[v], l, mid, key);
else return query(rt[u], rt[v], mid + 1, r, key - now);
}
int main()
{
int m, u, v, w;
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 tot = unique(b + 1, b + n + 1) - b - 1;
build(tree[0], 1, tot);
for(int i = 1; i <= n; i++)
{
int now = lower_bound(b + 1, b + tot + 1, a[i]) - b;
tree[i] = update(tree[i - 1], 1, tot, now);
}
while(m--)
{
scanf("%d %d %d", &u, &v, &w);
int ans = query(tree[u - 1], tree[v], 1, tot, w);
printf("%d\n", b[ans]);
}
return 0;
}