Word algorithm:
Chairman of the tree, also known as persistable tree line, is a historical version based on prefix and save ideas that can support a single point of modification, query the value of a location at a certain historical versions of data structure.
The main idea:
For our bold proposition above, we first consider the practice of violence:
For each state history, the establishment of a segment tree maintenance information current status.
Then you will find that the state transition and space consumption are very large, (edge \ (MLE \) side \ (TLE \) how it feels like) you will get a \ (TM (LE) ^ 2 \) results.
We then consider how to accelerate the transfer of state and compression space.
Taking into account only changes every time a modified single-point point, its impact is only at this point to the root of this chain, while other states are unchanged: So we do not need to update each node again, and is a new node has been altered, and then to the upper node of a tree, so that each time a state transition is compressed into \ (log (n) \) complexity, empathy space.
example:
The feeling is not very good against air or speak, so we look at a question:
Given a sequence of N integers will query its small K values within the range specified for the closed interval.
Lift the Chairman of the tree, almost everyone first thought was such a question. For Interval \ (K \) large, we established weights segment tree (i.e. the weight as the target segment tree, node weights represents the number of occurrences), the state transition using the above method, the \ (I \) trees weights segment tree maintenance interval \ ([1, i] \ ) information, each time using a query prefix and thought as the difference obtained intermediate state \ ([L, R & lt] \) , then look in the tree, if the total number of left subtree elements \ (\ geq k \) , description of the \ (k \) large in the left sub-tree, then into the left sub-tree recursively, otherwise go to the right subtree recursively, note into the right subtree recursively time the new \ (k \) to lose the left subtree \ (size \) .
Chairman of the tree of spatial complexity is \ (nlog (n) \) level, we generally will directly open \ (n << 5 \) spaceOr will fly to RE. Although the space consumption is still very large, but compared to the violence, it is still a superior approach.
Digression:
Chairman of sustainable thinking tree on the other algorithm has also been a corresponding application, such as an array can be persistent, be persistent Trie and so on.
So there are so many cancer data structure
Code:
#include<bits/stdc++.h>
#define N (200000 + 5)
using namespace std;
inline int read() {
int cnt = 0, f = 1; char c = getchar();
while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + c - '0'; c = getchar();}
return cnt * f;
}
int a[N], b[N * 2], n, m, q, rt[N], tot;
int x, y, k, res;
void Discretize() {
sort (b + 1, b + n + 1);
q = unique(b + 1, b + n + 1) - b - 1;
for (register int i = 1; i <= n; i++)
a[i] = lower_bound(b + 1, b + q + 1, a[i]) - b;
}
struct node{
int l, r, sum;
#define l(p) tree[p].l
#define r(p) tree[p].r
#define sum(p) tree[p].sum
}tree[N * 18];
void build(int &p, int l, int r) {
p = ++tot;
if (l == r) return;
int mid = (l + r) >> 1;
build (l(p), l, mid);
build (r(p), mid + 1, r);
}
void insert(int &p, int l, int r, int last, int pos) {
p = ++tot;
l(p) = l(last), r(p) = r(last);
sum(p) = sum(last) + 1;
if (l == r) return;
int mid = (l + r) >> 1;
if (pos <= mid) insert(l(p), l, mid, l(last), pos);
else insert(r(p), mid + 1, r, r(last), pos);
}
int query (int L, int R, int l, int r, int k) {
if (l == r) return l;
int mid = (l + r) >> 1;
int cnt = sum(l(R)) - sum(l(L));
if (k <= cnt) return query(l(L), l(R), l, mid, k);
else return query(r(L), r(R), mid + 1, r, k - cnt);
}
int main() {
n = read(); m = read();
for (register int i = 1; i <= n; i++) a[i] = b[i] = read();
Discretize();
build(rt[0], 1, q);
for (register int i = 1; i <= n; ++i) insert(rt[i], 1, q, rt[i - 1], a[i]);
while (m--) {
x = read(), y = read(), k = read();
res = query(rt[x - 1], rt[y], 1, q, k);
printf("%d\n", b[res]);
}
return 0;
}