首页 > 其他 > 详细

[洛谷P1801]黑匣子_NOI导刊2010提高(06)

时间:2018-10-27 13:55:43      阅读:113      评论:0      收藏:0      [点我收藏+]

题目大意:两个操作:向一个可重集中加入一个元素;询问第$k$大的数($k$为之前询问的个数加一)

题解:离散化,权值线段树直接查询

卡点:

 

C++ Code:

#include <cstdio>
#include <algorithm>
#define maxn 200010
int s[maxn], v[maxn];
int ret[maxn];
int n, m;
int V[maxn << 2];
void add(int rt, int l, int r, int pos) {
	V[rt]++;
	if (l == r) return ;
	int mid = l + r >> 1;
	if (pos <= mid) add(rt << 1, l, mid, pos);
	else add(rt << 1 | 1, mid + 1, r, pos);
}
int ask(int rt, int l, int r, int sz) {
	if (l == r) return l;
	int mid = l + r >> 1;
	if (sz <= V[rt << 1]) return ask(rt << 1, l, mid, sz);
	else return ask(rt << 1 | 1, mid + 1, r, sz - V[rt << 1]);
}
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%d", s + i);
		v[i] = s[i];
	}
	int tot = (std::sort(v + 1, v + n + 1), std::unique(v + 1, v + n + 1) - v - 1);
	for (int i = 1; i <= n; i++) {
		int tmp = s[i];
		s[i] = std::lower_bound(v + 1, v + tot + 1, tmp) - v;
		ret[s[i]] = tmp;
	}
	int last = 1;
	for (int i = 1, x; i <= m; i++) {
		scanf("%d", &x);
		for (; last <= x; last++) add(1, 1, n, s[last]);
		printf("%d\n", ret[ask(1, 1, n, i)]);
	}
	return 0;
}

  

[洛谷P1801]黑匣子_NOI导刊2010提高(06)

原文:https://www.cnblogs.com/Memory-of-winter/p/9860776.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!