主席树(
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)求区间第k小)
#include <bits/stdc++.h>
#define ll long long
#define endl "\n"
using namespace std;
const int inf = 0x3f3f3f3f;
int t;
int n, m, k;
struct PST
{
int nn, tot;
struct node
{
int lc, rc, sum;
node(){}
};
vector<node> tr;
vector<int> roots;
PST(int n1) : nn(n1), tot(0), tr(1), roots(1, 0)
{
build(1, nn, roots[0]);
}
#define lc(rt) tr[tr[rt].lc]
#define rc(rt) tr[tr[rt].rc]
void push_up(int rt)
{
tr[rt].sum = lc(rt).sum + rc(rt).sum;
}
void build(int l, int r, int& rt) {
rt = ++tot;
tr.emplace_back();
if (l == r)
return;
int mid = (l + r) >> 1;
int nb1, nb2;
build(l, mid, nb1);
tr[rt].lc = nb1;
build(mid + 1, r, nb2);
tr[rt].rc = nb2;
push_up(rt);
}
void update(int pos, int val, int l, int r, int old, int& rt)
{
rt = ++tot;
tr.emplace_back();
tr[rt] = tr[old];
if (l == r)
{
tr[rt].sum = tr[old].sum + val;
return;
}
int mid = (l + r) >> 1;
int nb;
if (pos <= mid)
{
update(pos, val, l, mid, tr[old].lc, nb);
tr[rt].lc = nb;
}
else
{
update(pos, val, mid + 1, r, tr[old].rc, nb);
tr[rt].rc = nb;
}
push_up(rt);
}
int update(int pos, int val)
{
int new_root;
update(pos, val, 1, nn, roots.back(), new_root);
roots.push_back(new_root);
return new_root;
}
int query(int u, int v, int l, int r, int kk)
{
if (l == r)
return l;
int mid = (l + r) >> 1;
int x = lc(v).sum - lc(u).sum;
if (kk <= x)
return query(tr[u].lc, tr[v].lc, l, mid, kk);
return query(tr[u].rc, tr[v].rc, mid + 1, r, kk - x);
}
int find_kth_smallest_num(int l, int r, int kk)
{
return query(roots[l - 1], roots[r], 1, nn, kk);
}
int find_kth_biggest_num(int l, int r, int kk)
{
int nb = r - l + 1;
return find_kth_smallest_num(l, r, nb + 1 - kk);
}
};
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i];
auto v = a;
sort(v.begin() + 1, v.end());
v.erase(unique(v.begin() + 1, v.end()), v.end());
PST tr(n);
auto getid = [&](int x)
{
return lower_bound(v.begin() + 1, v.end(), x) - v.begin();
};
while (m--)
{
int l, r, kk;
cin >> l >> r >> kk;
cout << v[tr.find_kth_smallest_num(l, r, kk)] << endl;
}
return 0;
}