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[N], mn[N], mx[N], 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[n] = P;
update(n);
}
}
else{
if(t[root].r)
Insert(t[root].r, now ^ 1);
else{
++ n;
t[root].r = n;
t[n] = 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;
}