Description
Give you a sequence and ask you the kth big number of a inteval.
Input
The first line is the number of the test cases.
For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere.
The second line contains n integers, describe the sequence.
Each of following m lines contains three integers s, t, k.
[s, t] indicates the interval and k indicates the kth big number in interval [s, t]
For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere.
The second line contains n integers, describe the sequence.
Each of following m lines contains three integers s, t, k.
[s, t] indicates the interval and k indicates the kth big number in interval [s, t]
Output
For each test case, output m lines. Each line contains the kth big number.
Sample Input
1 10 1 1 4 2 3 5 6 7 8 9 0 1 3 2
Sample Output
2
#include <iostream>
#include <algorithm>
#include <string.h>
#define MAXN 100010
using namespace std;
class Node
{
public:
int l, r;
};
class SGtree
{
public:
Node node[MAXN << 2];
int num_left[20][MAXN];
int sg_node[20][MAXN];
int parray[MAXN];
void init();
void Maketree(int i, int d, int l, int r);
int Query(int i, int d, int x, int y, int k);
}tree;
void SGtree::init()
{
memset(num_left, 0, sizeof(0));
memset(sg_node, 0, sizeof(sg_node));
memset(node, 0, sizeof(node));
}
void SGtree::Maketree(int o, int d, int l, int r)
{
node[o].l = l;
node[o].r = r;
if (l == r)
{
return ;
}
int mid = (l + r) >> 1;
int issame = mid - l + 1;
for (int i = l; i <= r; i++)
{
if (sg_node[d][i] < parray[mid])
{
issame--;
}
}
int pl = l, pr = mid + 1;
for (int i = l; i <= r; i++)
{
if (i == l)
{
num_left[d][i] = 0;
}
else
{
num_left[d][i] = num_left[d][i - 1];
}
if (sg_node[d][i] < parray[mid])
{
num_left[d][i]++;
sg_node[d + 1][pl++] = sg_node[d][i];
}
if (sg_node[d][i] > parray[mid])
{
sg_node[d + 1][pr++] = sg_node[d][i];
}
if (sg_node[d][i] == parray[mid])
{
if (issame > 0)
{
issame--;
num_left[d][i]++;
sg_node[d + 1][pl++] = sg_node[d][i];
}
else
{
sg_node[d + 1][pr++] = sg_node[d][i];
}
}
}
Maketree(2 * o, d + 1, l, mid);
Maketree(2 * o + 1, d + 1, mid + 1, r);
}
int SGtree::Query(int i, int d, int x, int y, int k)
{
int l = node[i].l;
int r = node[i].r;
int mid = (l + r) >> 1;
if (l == r)
{
return sg_node[d][x];
}
int lnum, ltornum;
if (x == node[i].l)
{
lnum = 0;
}
else
{
lnum = num_left[d][x - 1];
}
ltornum = num_left[d][y] - lnum;
if (ltornum >= k)
{
return Query(i * 2, d + 1, l + lnum, l + lnum + ltornum - 1, k);
}
else
{
int a = x - l - lnum;
int b = y - x - ltornum;
return Query(i * 2 + 1, d + 1, mid + a + 1, mid + a + b + 1, k - ltornum);
}
}
void input()
{
int t, n, m, x, y, k;
cin >> t;
while (t--)
{
scanf("%d %d", &n, &m);
tree.init();
for (int i = 1; i <= n; i++)
{
scanf("%d", &tree.parray[i]);
tree.sg_node[1][i] = tree.parray[i];
}
sort(tree.parray + 1, tree.parray + n + 1);
tree.Maketree(1, 1, 1, n);
while (m--)
{
scanf("%d %d %d", &x, &y, &k);
printf("%d\n", tree.Query(1, 1, x, y, k));
}
}
}
int main()
{
input();
return 0;
}