HDU 2665 Kth number
-
题意:求区间第k小的数【题面给的是 the kth big number 】(必须标红!!!!!各种debug,最后还是题面背锅……为啥写这种题面……吐槽……)
-
思路:主席树模板题。但是因为是多组输入,再加上题面的锅,让我一直以为是初始化错了。后来经过询问以及调试发现根本用不到初始化tree[ ]. 因为我们的第0棵树没有用过,一直就是空的。而后面的树又是继承前一棵树的,所以不需要初始化。【ps: 那么大,都清空肯定炸了……】
-
但是我还是不争气的去百度了如何memset结构体。因为真的不知道哪里错了www
memset(tree, 0x0, sizeof(*tree));
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define lowbit(x) x & (-x)
#define MID (l + r ) >> 1
#define lsn rt << 1
#define rsn rt << 1 | 1
#define Lson lsn, l, mid
#define Rson rsn, mid + 1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define eps 1e-6
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 1e5 + 5;
int n, m;
vector<int>vt, disc;
int root[maxN], tot, UP;
struct node{
int ls, rs, num;
node(int a = 0, int b = 0, int c = 0): ls(a), rs(b), num(c) {}
}tree[maxN * 20];
void init()
{
vt.clear();
disc.clear();
tot = 0;
}
void update(int &now, int pre, int l, int r, int k)
{
now = ++ tot;
tree[now] = node(tree[pre].ls, tree[pre].rs, tree[pre].num + 1);
if(l == r) return ;
int mid = MID;
if(mid >= k) update(tree[now].ls, tree[pre].ls, l, mid, k);
else update(tree[now].rs, tree[pre].rs, mid + 1, r, k);
}
int query(int i, int j, int l, int r, int k)
{
int dif = tree[tree[j].ls].num - tree[tree[i].ls].num;
int mid = MID;
if(l == r) return l;
if(dif >= k) return query(tree[i].ls, tree[j].ls, l, mid, k);
else return query(tree[i].rs, tree[j].rs, mid + 1, r, k - dif);
}
int main()
{
int TAT; scanf("%d", &TAT);
while(TAT -- )
{
init();
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i ++ )
{
int a; scanf("%d", &a);
vt.push_back(a);
disc.push_back(a);
}
sort(disc.begin(), disc.end());
disc.erase(unique(disc.begin(), disc.end()), disc.end());
UP = disc.size();
for(int i = 1; i <= n; i ++ )
{
int th = lower_bound(disc.begin(), disc.end(), vt[i - 1]) - disc.begin() + 1;
update(root[i], root[i - 1], 1, UP, th);
}
while(m -- )
{
int l, r, k; scanf("%d%d%d", &l, &r, &k);
//printf("%d\n", disc[query(root[l - 1], root[r], 1, UP, r - l + 1 + 1 - k) - 1]);
printf("%d\n", disc[query(root[l - 1], root[r], 1, UP, k) - 1]);
}
}
return 0;
}