题目链接
题的名称叫做“简单题”,实际上不简单——题记
没有任何的花里胡哨,卡了空间!!!
也就是说,只能用数据结构来维护咯,舍弃时间也不能浪费空间啊,多一丢丢都会MLE。
所以,就变成动态开点平衡二叉树操作吧,但是真的平衡嘛?KD Tree建树的话,跟输入有关,还真不平衡?怎么维护其平衡呢?那么就是替罪羊树不断的重构不平衡的二叉树吧,这里不能添加判断平衡的数组了,因为空间实在不管够啊,于是,直接每插入5000个点,就重构一下!
查询?查询当然暴力查啊,因为尽可能让它是一棵平衡二叉树,所以暴力查的话,基本上维持在log()左右。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
//#include <unordered_map>
//#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define eps 1e-8
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int K = 2, maxN = 2e5 + 7;
int N, root = 0, ch[maxN][2] = {0}, key[maxN], pp, tot = 0;
struct node
{
int d[K], val;
node(int a=0, int b=0, int c=0):d{a, b}, val(c) {}
friend bool operator < (node e1, node e2) { return e1.d[pp] < e2.d[pp]; }
} tree[maxN], p;
int mn[maxN][2], mx[maxN][2], sum[maxN] = {0};
inline void pushup(int rt)
{
for(int i=0; i<K; i++)
{
if(ch[rt][0] && ch[rt][1])
{
mn[rt][i] = min(tree[rt].d[i], min(mn[ch[rt][0]][i], mn[ch[rt][1]][i]));
mx[rt][i] = max(tree[rt].d[i], max(mx[ch[rt][0]][i], mx[ch[rt][1]][i]));
}
else if(ch[rt][0])
{
mn[rt][i] = min(tree[rt].d[i], mn[ch[rt][0]][i]);
mx[rt][i] = max(tree[rt].d[i], mx[ch[rt][0]][i]);
}
else if(ch[rt][1])
{
mn[rt][i] = min(tree[rt].d[i], mn[ch[rt][1]][i]);
mx[rt][i] = max(tree[rt].d[i], mx[ch[rt][1]][i]);
}
else mn[rt][i] = mx[rt][i] = tree[rt].d[i];
}
sum[rt] = sum[ch[rt][0]] + sum[ch[rt][1]] + tree[rt].val;
}
int build(int l, int r, int fa)
{
if(l > r) return 0;
int mid = HalF;
pp = key[fa] ^ 1;
key[mid] = pp;
nth_element(tree + l, tree + mid, tree + r + 1);
ch[mid][0] = build(l, mid - 1, mid);
ch[mid][1] = build(mid + 1, r, mid);
pushup(mid);
return mid;
}
void Insert(int &rt, int fa, int val)
{
pp = key[fa] ^ 1;
if(!rt)
{
rt = ++tot;
tree[rt] = p;
key[rt] = pp;
}
else Insert(ch[rt][tree[rt] < p], rt, val);
pushup(rt);
}
int x_1, y_1, x_2, y_2;
int query(int rt)
{
if(!rt) return 0;
if(mn[rt][0] > x_2 || mx[rt][0] < x_1 || mn[rt][1] > y_2 || mx[rt][1] < y_1) return 0;
int ans = 0;
if(mn[rt][0] >= x_1 && mx[rt][0] <= x_2 && mn[rt][1] >= y_1 && mx[rt][1] <= y_2) return sum[rt];
if(tree[rt].d[0] >= x_1 && tree[rt].d[0] <= x_2 && tree[rt].d[1] >= y_1 && tree[rt].d[1] <= y_2) ans += tree[rt].val;
ans += query(ch[rt][0]);
ans += query(ch[rt][1]);
return ans;
}
int main()
{
scanf("%d", &N);
int op, vv, ans = 0;
key[0] = 0;
while(scanf("%d", &op) && (op ^ 3))
{
if(op == 1)
{
scanf("%d%d%d", &x_1, &y_1, &vv); x_1 ^= ans; y_1 ^= ans; vv ^= ans;
p = node(x_1, y_1, vv);
Insert(root, 0, vv);
if(tot % 5000 == 0) root = build(1, tot, 0);
}
else
{
scanf("%d%d%d%d", &x_1, &y_1, &x_2, &y_2); x_1 ^= ans; y_1 ^= ans; x_2 ^= ans; y_2 ^= ans;
ans = query(root);
printf("%d\n", ans);
}
}
return 0;
}
/*
4
1 2 3 3
2 1 1 3 3
1 1 1 1
2 1 1 0 7
3
*/