首页 > 代码库 > [poj 2104] K-th Number【主席树】

[poj 2104] K-th Number【主席树】

传送门:http://poj.org/problem?id=2104

保存模版。

#include <cstdio>
#include <algorithm>
#include <cstring>

// Sora Sai Gou!!!

const int maxn = 100005, maxm = 5005, maxv = 2000005, nil = maxv - 1;

int n, m, a[maxn], b[maxn], siz[maxv], ch[maxv][2], root[maxv], cnt;
int t1, t2, t3;

inline int fndidx(int key) {
	int left = 1, right = n, mid;
	while (left < right) {
		mid = (left + right) >> 1;
		if (a[mid] < key) {
			left = mid + 1;
		}
		else {
			right = mid;
		}
	}
	return left;
}
void ist(int & ima, int p, int key, int ql, int qr) {
	if (!ima) {
		ima = ++cnt;
	}
	siz[ima] = siz[p] + 1;
	if (ql == qr) {
		return;
	}
	int mid = (ql + qr) >> 1;
	if (key <= mid) {
		ch[ima][1] = ch[p][1];
		ist(ch[ima][0], ch[p][0], key, ql, mid);
	}
	else {
		ch[ima][0] = ch[p][0];
		ist(ch[ima][1], ch[p][1], key, mid + 1, qr);
	}
}
inline int qry (int l, int r, int kth) {
	--l;
	int left = 1, right = n, mid, p1 = root[l], p2 = root[r], tem;
	while (left < right) {
		tem = siz[ch[p2][0]] - siz[ch[p1][0]];
		mid = (left + right) >> 1;
		if (kth <= tem) {
			p2 = ch[p2][0];
			p1 = ch[p1][0];
			right = mid;
		}
		else {
			kth -= tem;
			p2 = ch[p2][1];
			p1 = ch[p1][1];
			left = mid + 1;
		}
	}
	return a[left];
}

int main(void) {
	//freopen("in.txt", "r", stdin);
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", a + i);
	}
	memcpy(b, a, sizeof b);
	std::sort(a + 1, a + n + 1);
	for (int i = 1; i <= n; ++i) {
		b[i] = fndidx(b[i]);
	}
	
	for (int i = 1; i <= n; ++i) {
		ist(root[i], root[i - 1], b[i], 1, n);
	}
	for (int i = 0; i < m; ++i) {
		scanf("%d%d%d", &t1, &t2, &t3);
		printf("%d\n", qry(t1, t2, t3));
	}
	return 0;
}

  

[poj 2104] K-th Number【主席树】