洛谷P1533 可怜的狗狗 题解 主席树/可持久化线段树 求区间第k小模板题
题目链接:https://www.luogu.com.cn/problem/P1533
解题思路:
主席树求区间第k小模板题
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e7 + 5;
const int inf = INT_MAX;
int n, m, a, tr[maxn], ls[maxn], rs[maxn], rt[maxn], idx;
void push_up(int u) {
tr[u] = tr[ ls[u] ] + tr[ rs[u] ];
}
void ins(int p, int l, int r, int pu, int &u) {
if (!u)
u = ++idx;
if (l == r) {
tr[u] = 1;
return;
}
int mid = l + (r - l) / 2;
if (p <= mid) {
rs[u] = rs[pu];
ins(p, l, mid, ls[pu], ls[u]);
}
else {
ls[u] = ls[pu];
ins(p, mid+1, r, rs[pu], rs[u]);
}
push_up(u);
}
int query(int k, int l, int r, int pu, int u) {
if (l == r) {
return l;
}
int cnt = tr[ ls[u] ] - tr[ ls[pu] ], mid = l + (r - l) / 2;
if (cnt >= k)
return query(k, l, mid, ls[pu], ls[u]);
else
return query(k-cnt, mid+1, r, rs[pu], rs[u]);
}
void test(int l, int r, int u) {
if (!u) return;
if (l == r) return;
int mid = (l + r) / 2;
test(l, mid, ls[u]);
test(mid+1, r, rs[u]);
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &a);
ins(a, 0, inf, rt[i-1], rt[i]);
}
while (m--) {
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
printf("%d\n", query(k, 0, inf, rt[l-1], rt[r]));
}
return 0;
}