\(Code\)
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 2e5;
int n , m , rt[N + 5] , ind[N + 5] , a[N + 5] , len , size;
struct segment{
int ls , rs , sum;
}seg[(N << 5) + 5];
inline int read()
{
int res = 0;
char ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9') res = (res << 3) + (res << 1) + ch - '0' , ch = getchar();
return res;
}
inline int build(int l , int r)
{
int o = ++size;
if (l == r) return o;
int mid = (l + r) >> 1;
seg[o].ls = build(l , mid) , seg[o].rs = build(mid + 1 , r);
return o;
}
inline int update(int x , int l , int r , int rt)
{
int o = ++size;
seg[o].ls = seg[rt].ls , seg[o].rs = seg[rt].rs , seg[o].sum = seg[rt].sum + 1;
if (l == r && l == x) return o;
int mid = (l + r) >> 1;
if (x <= mid) seg[o].ls = update(x , l , mid , seg[rt].ls);
else seg[o].rs = update(x , mid + 1 , r , seg[rt].rs);
return o;
}
inline int query(int x , int y , int l , int r , int k)
{
if (l == r) return l;
int mid = (l + r) >> 1 , node = seg[seg[y].ls].sum - seg[seg[x].ls].sum;
if (node >= k) return query(seg[x].ls , seg[y].ls , l , mid , k);
else return query(seg[x].rs , seg[y].rs , mid + 1 , r , k - node);
}
int main()
{
n = read() , m = read();
for(register int i = 1; i <= n; i++) a[i] = read() , ind[i] = a[i];
sort(ind + 1 , ind + n + 1);
len = unique(ind + 1 , ind + n + 1) - ind - 1;
rt[0] = build(1 , len);
for(register int i = 1; i <= n; i++)
{
int x = lower_bound(ind + 1 , ind + len + 1 , a[i]) - ind;
rt[i] = update(x , 1 , len , rt[i - 1]);
}
int x , y , z;
for(register int i = 1; i <= m; i++)
{
x = read() , y = read() , z = read();
printf("%d\n" , ind[query(rt[x - 1] , rt[y] , 1 , len , z)]);
}
}
\(update\) 写法
int size, rt[N];
struct segment{int ls, rs, s;}seg[N * 16];
void update(int &p, int pre, int l, int r, int v)
{
p = ++size;
seg[p] = seg[pre], seg[p].s = seg[pre].s + 1;
if (l == r) return;
int mid = (l + r) >> 1;
if (v <= mid) update(seg[p].ls , seg[pre].ls, l, mid, v);
else update(seg[p].rs, seg[pre].rs, mid + 1, r, v);
}
int query(int p, int pre, int l, int r, int v)
{
int o = seg[p].s - seg[pre].s;
if (!o) return 0;
if (l == r) return o;
int mid = (l + r) >> 1;
if (v <= mid) return query(seg[p].ls, seg[pre].ls, l, mid, v);
return query(seg[p].rs, seg[pre].rs, mid + 1, r, v);
}