您的位置:首页 > 其它

[BZOJ 4066]简单题

2016-02-21 10:22 344 查看
K-D tree

矩形查询

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 200010
using namespace std;
void read(int& num){
	num = 0;
	int f = 1;
	char ch = getchar();
	for(; ch < '!'; ch = getchar());
	if(ch == '-'){
		ch = getchar();
		f = -1;
	}
	for(; ch > '!'; ch = getchar())
		num = num * 10 + ch - 48;
	num *= f;
}
int n, m, D;
#define N 2
struct Point{
	int d
, mn
, mx
, val, sum, l, r;
	bool operator<(const Point& k)const{
		return d[D] < k.d[D];
	}
	bool operator==(const Point& k)const{
		return d[0] == k.d[0] && d[1] == k.d[1];
	}
	int& operator[](int i){return d[i];}
	Point(int x = 0, int y = 0){
		d[0] = x, d[1] = y;
		val = sum = l = r = 0;
	}
}t[maxn], P;

int root;

void update(int x){
	int l = t[x].l, r = t[x].r;
	t[x].sum = t[l].sum + t[r].sum + t[x].val;
	for(int i = 0; i < N; i ++){
		t[x].mn[i] = t[x].mx[i] = t[x][i];
		if(l){
			t[x].mn[i] = min(t[x].mn[i], t[l].mn[i]);
			t[x].mx[i] = max(t[x].mx[i], t[l].mx[i]);
		}
		if(r){
            t[x].mn[i] = min(t[x].mn[i], t[r].mn[i]);
			t[x].mx[i] = max(t[x].mx[i], t[r].mx[i]);
		}
	}
}

int build(int l, int r, int now){
	if(l > r)return 0;
	D = now;
	int mid = l + r >> 1;
	nth_element(t + l, t + mid, t + r + 1);
	t[mid].l = build(l, mid - 1, now ^ 1);
	t[mid].r = build(mid + 1, r, now ^ 1);
	update(mid);
	return mid;
}

void Insert(int root, int now){
	D = now;
	if(P == t[root]){
		t[root].val += P.val;
		t[root].sum += P.sum;
		return;
	}
	if(P < t[root]){
		if(t[root].l)
		    Insert(t[root].l, now ^ 1);
		else{
			++ n;
			t[root].l = n;
			t
 = P;
			update(n);
		}
	}
	else{
		if(t[root].r)
		    Insert(t[root].r, now ^ 1);
		else{
			++ n;
			t[root].r = n;
			t
 = P;
			update(n);
		}
	}
	update(root);
}

bool init(int x1, int y1, int x2, int y2, int X1, int Y1, int X2, int Y2){
	return X1 <= x1 && Y1 <= y1 && X2 >= x2 && Y2 >= y2;
}

bool outit(int x1, int y1, int x2, int y2, int X1, int Y1, int X2, int Y2){
	return x2 < X1 || x1 > X2 || y2 < Y1 || y1 > Y2;
}

int x1, y1, x2, y2;
int ask(int root){
	if(init(t[root].mn[0], t[root].mn[1], t[root].mx[0], t[root].mx[1], x1, y1, x2, y2))
		return t[root].sum;
	if(outit(t[root].mn[0], t[root].mn[1], t[root].mx[0], t[root].mx[1], x1, y1, x2, y2))
	    return 0;
	int ret = 0;
	if(init(t[root][0], t[root][1], t[root][0], t[root][1], x1, y1, x2, y2))
	    ret += t[root].val;
	if(t[root].l)ret += ask(t[root].l);
	if(t[root].r)ret += ask(t[root].r);
	return ret;
}

int main(){
	int Buf = 0, type, a, lastans = 0;
	read(type);
	while(true){
		read(type);
		if(type == 2){
            read(x1), read(y1), read(x2), read(y2);
            printf("0\n");
		}
		else{
            read(x1), read(y1), read(a);
            root = ++ n;
			t[root] = Point(x1, y1);
			t[root].sum = t[root].val = a;
			update(root);
			break;
		}
	}
	while(true){
		read(type);
		if(type == 3)break;
		if(type == 1){
			read(x1), read(y1), read(a);
			x1 ^= lastans, y1 ^= lastans, a ^= lastans;
			P = Point(x1, y1);
			P.sum = P.val = a;
			Insert(root, 0);
			Buf ++;
			if(Buf == 10000){
				root = build(1, n, 0);
				Buf = 0;
			}
		}
		else{
			read(x1), read(y1), read(x2), read(y2);
			x1 ^= lastans, y1 ^= lastans;
			x2 ^= lastans, y2 ^= lastans;
			lastans = 0;
			printf("%d\n", lastans = ask(root));
		}
	}

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: