平衡树空间树套树练手题

废话就不多说了,开始。。。

    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!”

你可能感兴趣的:(树)