您的位置:首页 > 其它

POJ 2104 K-th Number——主席树

2018-03-10 15:46 344 查看
一开始分块搞过了,但后来ac代码交上去TLE,怀疑是加强数据或者当时是运气过的,于是学了主席树,推荐这篇博客
http://blog.csdn.net/creatorx/article/details/75446472
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int n, m, cnt;
struct Node {
int L, R, sum;
Node () { sum = 0; }
}tree[maxn*20];
struct Value {
int x, id;
bool operator < (const Value &rhs) const {
return x < rhs.x;
}
}value[maxn];
int root[maxn], ran[maxn];
void init() {
cnt = 1;
root[0] = 0;
tree[0].L = tree[0].R = tree[0].sum = 0;
}
void update(int num, int &rt, int l, int r) {
tree[cnt++] = tree[rt];
rt = cnt - 1;
tree[rt].sum++;
if (l == r) return;
int mid = (l + r)>>1;
if (num <= mid) update(num, tree[rt].L, l, mid);
else update(num, tree[rt].R, mid + 1, r);
}
int query(int i, int j, int k, int l, int r) {
int d = tree[tree[j].L].sum - tree[tree[i].L].sum;
if (l == r) return l;
int mid = (l+r)>>1;
if (k <= d) return query(tree[i].L, tree[j].L, k, l, mid);
else return query(tree[i].R, tree[j].R, k-d, mid + 1, r);
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &value[i].x);
value[i].id = i;
}
sort(value+1, value+1+n);
for (int i = 1; i <= n; i++) ran[value[i].id] = i;
init();
for (int i = 1; i <= n; i++) {
root[i] = root[i-1];
update(ran[i], root[i], 1, n);
}
int left, right, k;
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &left, &right, &k);
printf("%d\n", value[query(root[left-1], root[right], k, 1, n)].x);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: