平衡树空间树套树练手题
废话就不多说了,开始。。。
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26976
纯属无聊,练手用的,线段树套平衡树常数太大超时了,改成树状组数套平衡树就AC了。。。。
其实感到如果是100000次作操,坐标的围范都是100000,那二维线段树或者二维树状组数就搞不定了吧,空间开不下,只能离散化失落一维,然后将一另维入插平衡树。
套了平衡树以后有个处好就是省空间。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define L x->c[0]
#define R x->c[1]
#define KT root->c[1]->c[0]
const int maxn = 100010;
struct node {
struct node *c[2], *fa;
int id;
int sz;
int val;
inline void up() {
sz = c[0]->sz + c[1]->sz + 1;
}
} NODE[maxn], *null = &NODE[0];
int top;
struct SplayTree {
node *root;
inline void Rotate(node *x, int p) {
node *y = x->fa;
y->c[!p] = x->c[p];
x->c[p]->fa = y;
x->fa = y->fa;
if (x->fa != null)
y->fa->c[y->fa->c[1] == y] = x;
x->c[p] = y;
y->fa = x;
y->up();
}
inline void Splay(node *x, node *goal) {
while (x->fa != goal) {
node *y = x->fa, *z = y->fa;
int f = z->c[0] == y, g = y->c[f] == x;
if (z != goal)
Rotate(g ? x : y, f ^ g);
Rotate(x, x->fa->c[0] == x);
}
x->up();
if (goal == null)
root = x;
}
inline void RTO(int k, node *goal) {
node *x = root;
while (L->sz + 1 != k) {
if(k < L->sz + 1) x = L;
else {
k -= L->sz + 1;
x = R;
}
}
Splay(x, goal);
}
node *new_node(node *fa, int v) {
node *x = &NODE[++top];
x->id = top;
x->c[0] = x->c[1] = null;
x->sz = 1;
x->val = v;
x->fa = fa;
return x;
}
void vist(node *x) {
if (x != null) {
printf("节点:%2d : 左儿子: %2d 右儿子: %2d sz: %2d val:%2d\n", x->id,
x->c[0]->id, x->c[1]->id, x->sz, x->val);
vist(x->c[0]);
vist(x->c[1]);
}
}
void debug() {
vist(root);
}
inline bool find(node* x, int v) {
if (x == null)
return false;
if (x->val == v)
return true;
if (v < x->val) {
return find(x->c[0], v);
} else
return find(x->c[1], v);
}
bool find(int v) {
return find(root, v);
}
void insert(node* &x, node* y) {
if (x == null) {
x = y;
return;
}
if (y->val < x->val) {
insert(x->c[0], y);
x->c[0]->fa = x;
} else {
insert(x->c[1], y);
x->c[1]->fa = x;
}
x->up();
}
node* find_succ(node*x, int v) {
if (x == null)
return x;
if (x->val > v) {
node* tmp = find_succ(x->c[0], v);
return tmp==null ? x : tmp;
} else {
return find_succ(x->c[1], v);
}
}
void insert(int v) {
node *tmp = new_node(null, v);
if(root==null) root = tmp;
else insert(root, tmp);
Splay(tmp, null);
}
int query(int y1, int y2) {
node* a = find_succ(root, y2);
int A, B;
if (a == null)
A = root->sz;
else {
Splay(a, null);
A = root->c[0]->sz;
}
a = find_succ(root, y1 - 1);
if (a == null)
B = root->sz;
else {
Splay(a, null);
B = root->c[0]->sz;
}
return A - B;
}
void clear() {
root = null;
}
};
void prepare() {
top = 0;
null->id = 0;
null->c[0] = null->c[1] = null->fa = NULL;
null->sz = null->val = 0;
}
const int MAX = 1005;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct BIT {
SplayTree spt[1010];
void build() {
for(int i = 0; i <= MAX;i ++) spt[i].clear();
}
void update(int x,int y) {
for(;x<=MAX;x+=x&-x) spt[x].insert(y);
}
int query(int x,int y1,int y2) {
int ans = 0;
for(;x;x-=x&-x) ans += spt[x].query(y1,y2);
return ans;
}
int query(int x1, int x2, int y1, int y2) {
return query(x2,y1,y2) - query(x1-1,y1,y2);
}
} seg;
int main() {
int t, ca = 1, q, op , x, y, x1, y1, x2, y2;
scanf("%d", &t);
while (t--) {
scanf("%d", &q);
prepare();
seg.build();
printf("Case %d:\n", ca++);
while (q--) {
scanf("%d", &op);
if (op == 0) {
scanf("%d%d",&x,&y);
x++;y++;
if (seg.query(x, x,y,y)) continue;
seg.update(x, y);
} else {
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x1++;y1++;x2++;y2++;
printf("%d\n", seg.query(x1, x2, y1, y2));
}
}
}
return 0;
}
文章结束给大家分享下程序员的一些笑话语录: 一位程序员去海边游泳,由于水性不佳,游不回岸了,于是他挥着手臂,大声求.救:“F1,F1!”

浙公网安备 33010602011771号