Problem 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]
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
思路
普通的主席树求给定区间第k大,如果不会的去看我以前的博客。。
代码
#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <sstream>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#include <list>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
const int N = 2e5 + 10;
const int inf = 0x3f3f3f3f;
int node_cnt, n, m;
int sum[N << 5], rt[N], lc[N << 5], rc[N << 5];
int a[N], b[N], p; //原序列和离散序列和修改点
void build(int &t, int l, int r)
{
t = ++node_cnt;
if (l == r)
return;
int mid = (l + r) >> 1;
build(lc[t], l, mid);
build(rc[t], mid + 1, r);
}
int modify(int o, int l, int r)
{
int oo = ++node_cnt;
lc[oo] = lc[o];
rc[oo] = rc[o];
sum[oo] = sum[o] + 1;
if (l == r)
return oo;
int mid = (l + r) >> 1;
if (p <= mid)
lc[oo] = modify(lc[oo], l, mid);
else
rc[oo] = modify(rc[oo], mid + 1, r);
return oo;
}
int query(int u, int v, int l, int r, int k) //求u,v这两棵线段树的差的树中的第k大
{
int mid = (l + r) >> 1, ans;
int x = sum[lc[v]] - sum[lc[u]];
if (l == r)
return l;
if (x >= k)
ans = query(lc[u], lc[v], l, mid, k);
else
ans = query(rc[u], rc[v], mid + 1, r, k - x);
return ans;
}
void init()
{
node_cnt = 0;
}
int main()
{
//freopen("in.txt", "r", stdin);
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
init();
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
b[i] = a[i];
}
sort(b + 1, b + n + 1);
int q = unique(b + 1, b + n + 1) - (b + 1);
build(rt[0], 1, q);
for (int i = 1; i <= n; i++)
{
p = lower_bound(b + 1, b + q + 1, a[i]) - b;
rt[i] = modify(rt[i - 1], 1, q);
}
int l, r, k;
while (m--)
{
scanf("%d%d%d", &l, &r, &k);
int ans = query(rt[l - 1], rt[r], 1, q, k);
printf("%d\n", b[ans]);
}
}
return 0;
}