[luogu3369][普通平衡树]

Posted wxyww

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu3369][普通平衡树]相关的知识,希望对你有一定的参考价值。

题目链接

思路

模板

只是有几个容易出错的地方

第45行容易忘记

第54行里面的cnt--和siz--容易忘记

第56行是根据id判断不是val

第60行siz--容易忘记

第64行是siz+1不是siz+cnt

第77行和82行等于的情况容易忽略

代码

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<ctime>
#define ls TR[cur].ch[0]
#define rs TR[cur].ch[1]
using namespace std;
typedef long long ll;
const int N = 100000 + 100,INF = 1e7 + 100;
ll read() {
    ll x = 0,f = 1;char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x * f;
}
struct node {
    int ch[2],val,id,cnt,siz;
}TR[N];
void up(int cur) {
    TR[cur].siz = TR[ls].siz + TR[rs].siz + TR[cur].cnt;
}
void rotate(int &cur,int f) {
    int son = TR[cur].ch[f];
    TR[cur].ch[f] = TR[son].ch[f ^ 1];
    TR[son].ch[f ^ 1] = cur;
    up(cur);
    cur = son;
    up(cur);
}
int tot;
void insert(int &cur,int val) {
    if(!cur) {
        cur = ++tot;
        TR[cur].val = val;
        TR[cur].id = rand();
        TR[cur].cnt = TR[cur].siz = 1;
        return;
    }
    TR[cur].siz++;//!!
    if(TR[cur].val == val) { TR[cur].cnt++;return;}
    int d = val > TR[cur].val;
    insert(TR[cur].ch[d],val);
    if(TR[TR[cur].ch[d]].id < TR[cur].id) rotate(cur,d);
}
void del(int &cur,int val) {
    if(!cur) return;
    if(val == TR[cur].val) {
        if(TR[cur].cnt > 1) {TR[cur].cnt--;TR[cur].siz--; return;}
        if(!ls || !rs) {cur = ls + rs;return;}
        int d = TR[rs].id < TR[ls].id;
        rotate(cur,d);
        del(cur,val);
    }
    else TR[cur].siz--,del(TR[cur].ch[val > TR[cur].val],val);
}
int Rank(int cur,int val) {
    if(!cur) return 0;
    if(val == TR[cur].val) return TR[ls].siz + 1;
    if(val < TR[cur].val) return Rank(ls,val);
    return Rank(rs,val) + TR[ls].siz + TR[cur].cnt;
}
int kth(int cur,int now) {
    while(1) {
        if(TR[ls].siz >= now) cur = ls;
        else if(TR[ls].siz + TR[cur].cnt < now) now -=TR[ls].siz + TR[cur].cnt,cur = rs;
        else return TR[cur].val;
    }
}
int pred(int cur,int val) {
    if(!cur) return -INF;
    if(val <= TR[cur].val) return pred(ls,val);//!!!
    return max(pred(rs,val),TR[cur].val);
}
int nex(int cur,int val) {
    if(!cur) return INF;
    if(val >= TR[cur].val) return nex(rs,val);//!!!
    return min(nex(ls,val),TR[cur].val);
}
int main() {
    srand(time(0));
    int n = read();
    int rt = 0;
    while(n--) {
        int opt = read(),x = read();
        if(opt == 1) insert(rt,x);
        if(opt == 2) del(rt,x);
        if(opt == 3) printf("%d
",Rank(rt,x));
        if(opt == 4) printf("%d
",kth(rt,x));
        if(opt == 5) printf("%d
",pred(rt,x));
        if(opt == 6) printf("%d
",nex(rt,x));
    }

    return 0;
}

一言

记忆或会消失,但我的心会记着承诺。

以上是关于[luogu3369][普通平衡树]的主要内容,如果未能解决你的问题,请参考以下文章

[luogu3369]普通平衡树(替罪羊树模板)

luogu P3369 普通平衡树

luogu P3369 普通平衡树

替罪羊树 ------ luogu P3369 模板普通平衡树(Treap/SBT)

红黑树 ------ luogu P3369 模板普通平衡树(Treap/SBT)

luogu P3369 模板普通平衡树(Treap/SBT)