【BZOJ3524】[Poi2014]Couriers【主席树】

【题目链接】

比较裸的主席树,注意下标不要手滑写错了。

/* Pigonometry */
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 500005, maxnode = 10000005;

int n, m;

int son[maxnode][2], sum[maxnode], segcnt, root[maxn];

inline int iread() {
	int f = 1, x = 0; char ch = getchar();
	for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return f * x;
}

inline void insert(int x, int &y, int l, int r, int c) {
	y = ++segcnt;
	sum[y] = sum[x] + 1;
	if(l == r) return;
	int mid = l + r >> 1;
	son[y][0] = son[x][0]; son[y][1] = son[x][1];
	if(c <= mid) insert(son[x][0], son[y][0], l, mid, c);
	else insert(son[x][1], son[y][1], mid + 1, r, c);
}

inline int query(int x, int y, int k) {
	int l = 1, r = n;
	while(l < r) {
		int mid = l + r >> 1;
		if(sum[son[y][0]] - sum[son[x][0]] > k) x = son[x][0], y = son[y][0], r = mid;
		else if(sum[son[y][1]] - sum[son[x][1]] > k) x = son[x][1], y = son[y][1], l = mid + 1;
		else return 0;
	}
	return l;
}

int main() {
	n = iread(); m = iread();
	for(int i = 1; i <= n; i++) {
		int x = iread();
		insert(root[i - 1], root[i], 1, n, x);
	}
	while(m--) {
		int l = iread(), r = iread();
		printf("%d\n", query(root[l - 1], root[r], (r - l + 1) >> 1));
	}
	return 0;
}


你可能感兴趣的:(主席树)