I've been trying to solve this problem with wavelet tree, and optimize by discrete the values from $$$[-10^9, 10^9]$$$ to $$$[0, N - 1]$$$. I keep getting runtime error.
Code
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
struct splitmix64_hash {
static unsigned long long splitmix64(unsigned long long x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
unsigned long long operator()(unsigned long long x) const {
static const unsigned long long FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
template<class T, class U, class H = splitmix64_hash> using hash_map = gp_hash_table<T, U, H>;
template<class T, class H = splitmix64_hash> using hash_set = hash_map<T, null_type, H>;
template<class T>
class wavelet {
public:
wavelet(T* from, T* to, T L, T R) : low(L), high(R) {
if(low == high || from >= to) {
return;
}
T mid = low + (high - low) / 2;
auto f = [mid](T x) {
return x <= mid;
};
a.reserve(to - from + 1);
a.push_back(0);
for(auto it = from; it != to; ++it) {
a.push_back(a.back() + f(*it));
}
auto p = stable_partition(from, to, f);
l = new wavelet(from, p, low, mid);
r = new wavelet(p, to, mid + 1, high);
}
// return kth smallest element in [L, R]
T kth(int L, int R, int k) {
if(L > R) {
return 0;
}
if(low == high) {
return low;
}
int lb = a[L - 1];
int rb = a[R];
int lhs = rb - lb;
if(k <= lhs) {
return l->kth(lb + 1, rb, k);
}
return r->kth(L - lb, R - rb, k - lhs);
}
// return number of elements in [L, R] <= k
int leq(int L, int R, T k) {
if(L > R || k < low) {
return 0;
}
if(high <= k) {
return R - L + 1;
}
int lb = a[L - 1];
int rb = a[R];
return l->leq(lb + 1, rb, k) + r->leq(l - lb, r - rb, k);
}
// return number of elements in [L, R] == k
int count(int L, int R, T k) {
if(L > R || k < low || k > high) {
return 0;
}
if(low == high) {
return R - L + 1;
}
int lb = a[L - 1];
int rb = a[R];
T mid = low + (high - low) / 2;
if(k <= mid) {
return l->count(lb + 1, rb, k);
}
return r->count(L - lb, R - rb, k);
}
~wavelet() {
delete l;
delete r;
}
private:
T low, high;
wavelet* l;
wavelet* r;
vector<T> a;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, q;
cin >> n >> q;
int* a = new int[n];
vector<int> xs(n);
for(int i = 0; i < n; ++i) {
cin >> a[i];
xs[i] = a[i];
}
sort(xs.begin(), xs.end());
hash_map<int, int> mp;
for(int i = 0; i < n; ++i) {
int id = lower_bound(xs.begin(), xs.end(), a[i]) - xs.begin();
mp[id] = a[i];
a[i] = id;
}
wavelet<int> T(a, a + n, 0, n - 1);
while(q--) {
int l, r, k;
cin >> l >> r >> k;
cout << mp[T.kth(l, r, k)] << "\n";
}
return 0;
}