hdu5820 Lights

主席树 但是能够想到题解的做法很难

#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>

using namespace std;

const int MAXN = 500010;
int n;
vector<int> p[50010];
int T[50010];
struct Node{
	int s;
	int ls, rs;
}tree[MAXN * 16];
int tot;
int x[50010];
int add(int x,int l,int r,int pre) {
	int rt = ++tot;
	tree[rt] = tree[pre];
	tree[rt].s ++;
	if(l == r) return rt;
	int m = (l+r) >>1;
	if(x <= m) tree[rt].ls = add(x,l,m,tree[pre].ls);
	else tree[rt].rs = add(x,m+1,r,tree[pre].rs);
	return rt;
}
int query(int s,int t,int l, int r, int rt1, int rt2){
	if(s <= l && r <= t) return tree[rt2].s-tree[rt1].s;
	int m = (l+r) >>1;
	int ans = 0;

	if(s <= m) ans += query(s,t,l,m,tree[rt1].ls,tree[rt2].ls);
	if(t > m)  ans += query(s,t,m+1,r,tree[rt1].rs,tree[rt2].rs);
	return ans;
}

void init()
{
	for (int i = 1; i <= 50000; ++i) p[i].clear();
	while (n--) {
		int x, y;
		scanf("%d%d", &x, &y);
		p[x].push_back(y);
	}
	for (int i = 1; i <= 50000; ++i) {
		sort(p[i].begin(), p[i].end());
		p[i].erase(unique(p[i].begin(), p[i].end()), p[i].end());
	}
}

bool solve()
{
	tot = 0;
	tree[0].ls = tree[0].rs = tree[0].s = 0; T[0] = 0;
	memset(x, 0, sizeof(x));
	for (int i = 1; i <= 50000; ++i) {
		T[i] = T[i - 1];
		for (int j = 0; j < (int)p[i].size(); ++j) {
			int l = j == 0 ? 0 : p[i][j - 1];
			int r = j == (int)p[i].size() - 1 ? 50001 : p[i][j + 1];
			if (query( l + 1, r - 1,1,50000,T[i], T[x[p[i][j]]])) {
				return false;
			}
		}
		for (int j = 0; j < (int)p[i].size(); ++j) {
			T[i] = add(p[i][j], 1, 50000, T[i]);
			x[p[i][j]] = i;
		}
	}
	return true;
}

int main()
{
//	freopen("1012.in","r",stdin);
	while (scanf("%d", &n), n > 0) {
		init();
		puts(solve() ? "YES" : "NO");
	}
}                                 


原文地址:https://www.cnblogs.com/Basasuya/p/8433759.html