洛谷【P3369】普通平衡树(AVL树做法)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
struct node{
    int l, r, val, height, size;
}tree[maxn];
int t, tot, root;

inline int read(){
    int s = 0, w = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * w;
}

inline void print(int x){
    if(x < 0) x = ~x + 1, putchar('-');
    if(x > 9) print(x / 10);
    putchar(x % 10 + '0');
}

inline void newnode(int &now, int val){
    tree[now=++tot].val = val;
    tree[tot].size = 1;
}

inline void update(int now){
    tree[now].size = tree[tree[now].l].size + tree[tree[now].r].size + 1;
    tree[now].height = max(tree[tree[now].l].height, tree[tree[now].r].height) + 1;
}

inline int factor(int now){///获取平衡因子
    return tree[tree[now].l].height - tree[tree[now].r].height;
}

inline void lrotate(int &now){///左旋
    int r = tree[now].r;
    tree[now].r = tree[r].l;
    tree[r].l = now;
    now = r;
    update(tree[now].l), update(now);
}

inline void rrotate(int &now){///右旋
    int l = tree[now].l;
    tree[now].l = tree[l].r;
    tree[l].r = now;
    now = l;
    update(tree[now].r), update(now);
}

inline void check(int &now){
    int nf = factor(now);
    if(nf > 1){
        int lf = factor(tree[now].l);
        if(lf > 0) rrotate(now);                      ///LL
        else lrotate(tree[now].l), rrotate(now);      ///LR
    }
    else if(nf < -1){
        int rf = factor(tree[now].r);
        if(rf < 0) lrotate(now);                      ///RR
        else rrotate(tree[now].r), lrotate(now);      ///RL
    }
    else if(now) update(now);
}

void ins(int &now, int val){
    if(!now) newnode(now, val);
    else if(val < tree[now].val) ins(tree[now].l, val);
    else ins(tree[now].r, val);
    check(now);
}

int find(int &now, int fa){///找到要删除节点的后继
    int ret;
    if(!tree[now].l){
        ret = now;
        tree[fa].l = tree[now].r;
    }
    else{
        ret = find(tree[now].l, now);
        check(now);
    }
    return ret;
}

void del(int &now, int val){
    if(val == tree[now].val){
        int l = tree[now].l, r = tree[now].r;
        if(!l || !r) now = l + r;
        else{
            now = find(r, r);
            if(now!=r) tree[now].r = r;
            tree[now].l = l;
        }
    }
    else if(val < tree[now].val) del(tree[now].l, val);
    else del(tree[now].r, val);
    check(now);
}

int getrank(int val){
    int now = root, rank = 1;
    while(now){
        if(val <= tree[now].val) now=tree[now].l;
        else{
            rank += tree[tree[now].l].size + 1;
            now = tree[now].r;
        }
    }
    return rank;
}

int getnum(int rank){
    int now = root;
    while(now){
        if(tree[tree[now].l].size + 1 == rank) break;
        else if(tree[tree[now].l].size >= rank) now=tree[now].l;
        else{
            rank -= tree[tree[now].l].size + 1;
            now = tree[now].r;
        }
    }
    return tree[now].val;
}

int main(){
    t = read();
    while(t--){
        int op, x;
        op = read(), x = read();
        if(op == 1) ins(root, x);
        else if(op == 2) del(root, x);
        else if(op == 3) print(getrank(x)), putchar('\n');
        else if(op == 4) print(getnum(x)), putchar('\n');
        else if(op == 5) print(getnum(getrank(x) - 1)), putchar('\n');
        else print(getnum(getrank(x + 1))), putchar('\n');
    }
    
    return 0;
}
/*
* ┌───┐   ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
* │Esc│   │ F1│ F2│ F3│ F4│ │ F5│ F6│ F7│ F8│ │ F9│F10│F11│F12│ │P/S│S L│P/B│  ┌┐    ┌┐    ┌┐
* └───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘  └┘    └┘    └┘
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
* │~ `│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ BacSp │ │Ins│Hom│PUp│ │Num│ / │ * │ - │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
* │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│ | \ │ │Del│End│PDn│ │ 7 │ 8 │ 9 │   │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │
* │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter  │               │ 4 │ 5 │ 6 │   │
* ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤     ┌───┐     ├───┼───┼───┼───┤
* │ Shift  │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│  Shift   │     │ ↑ │     │ 1 │ 2 │ 3 │   │
* ├─────┬──┴─┬─┴──┬┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤ E││
* │ Ctrl│ Win│ Alt│         Space         │ Alt│ Win│Menu│Ctrl│ │ ← │ ↓ │ → │ │   0   │ . │←─┘│
* └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
*/

全部评论

相关推荐

头像
今天 12:47
已编辑
中国地质大学(武汉) Java
你出生在农村,与其它农村小孩子无异小学时你对成绩没有概念,只感觉上课不听课也是无聊,只知道不写完作业会被老师罚站一到考试,自己成绩总是名列靠前,即使偶尔落后,你也从不在意中学时你觉得课本的东西很简单,随便学学就会了,并没有大量刷题你总是想不通,那些所谓的数学物理中难题,明明是在送分,为什么你的同学总是想不出解题方法高中时这三年你过的不容易,晚睡早起,给了自己很多压力.但是你也发现自己是有些小聪明的,你感觉班里有些同学很刻苦,但成绩比你差远了。那些数学题和物理题的陷阱,同学一遍遍踩坑,但是你总能发现并避开它们.“为了父母的期盼,为了恩师的厚望,为了天赐的智慧,为了青春的理想......”“天行健...
创作助手_刘北:其实,这种已经是神童级别的了,不费吹灰之力就能拿到自己想要的东西,就像机器按照程序走了一遍,就像我小时候看爱情公寓,觉得他们都很惨,几个人只能挤在一个房间里合租,但是好在他们有一群非常好的朋友,随着时间的推移,慢慢长大了,在看爱情公寓的时候,觉得他们都很厉害,博士、留学生、***、电台公子,数学天才,任何一个都是我可望而不可即的,更别说可以在异地认识一群更好的朋友了,所以呢,人还是要自给自足,满足当下,不要攀比,意气风发的且有理想的18岁少年永远都存在,只不过随着时间的推移他被你包裹在了洋葱的最深处。
点赞 评论 收藏
分享
你背过凌晨4点的八股文么:简历挂了的话会是流程终止,像我一样
点赞 评论 收藏
分享
高斯林的信徒:武大简历挂?我勒个骚岗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务