废话就不多说了,开始。。。
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!”