#include <iostream> #include <vector> #include <algorithm> int allocArray[1'660'965 + 100'000]; int allocIndex = 0; int* NewInt(int size) noexcept { int* ret = allocArray + allocIndex; allocIndex += size; return ret; } struct Range { int start, end; bool Include(Range outer) const noexcept { return outer.start <= start && end <= outer.end; } bool Exclude(Range outer) const noexcept { return outer.end < start || end < outer.start; } bool IsLeaf() const noexcept { return start == end; } int Count() const noexcept { return 1 + end - start; } }; class Node { public: inline static int* InitArray; public: explicit Node(Range r) noexcept : range(r) { if (range.IsLeaf()) { (array = NewInt(n = 1))[0] = InitArray[range.start]; return; } int mid = range.start + (range.end - range.start) / 2; left = new Node({ range.start, mid }); right = new Node({ mid + 1, range.end }); array = NewInt(n = range.Count()); std::merge(left->array, left->array + left->n, right->array, right->array + right->n, array); } ~Node() { delete left; delete right; } int LessCount(Range query, int value) const noexcept { if (range.Exclude(query)) { return 0; } if (range.Include(query)) { return static_cast<int>(std::lower_bound(array, array + n, value) - array); } return left->LessCount(query, value) + right->LessCount(query, value); } int GetMinimum() const noexcept { return array[0]; } int GetMaximum() const noexcept { return array[n-1]; } private: Range range; Node* left = nullptr, * right = nullptr; int* array; int n; }; int main() noexcept { std::cin.tie(nullptr)->sync_with_stdio(false); int n, q; std::cin >> n >> q; Node::InitArray = NewInt(n); for (int i = 0; i < n; ++i) { std::cin >> Node::InitArray[i]; } Node* const root = new Node({ 0, n - 1 }); const int minValue = root->GetMinimum(); const int maxValue = root->GetMaximum(); for (int i = 0; i < q; ++i) { int l, r, k; std::cin >> l >> r >> k; const Range query{ l - 1, r - 1 }; int low = minValue; for (int high = maxValue, mid; low < high; ) { mid = low + (high - low) / 2; if (root->LessCount(query, mid + 1) < k) { low = mid + 1; } else { high = mid; } } std::cout << low << '\n'; } return 0; }
7 3 1 5 2 6 3 7 4 2 5 3 4 4 1 1 7 3
5 6 3
The brand new service which powers Ideone!
Widget for compiling and running the source code in a web browser!