樹套樹練手題

來源:互聯網
上載者:User

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|1struct 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;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.