初前两个点全RE,求调,悬赏关注!!!
查看原帖
初前两个点全RE,求调,悬赏关注!!!
797354
Ferdina_zcjb楼主2023/8/29 11:54
#include <bits/stdc++.h>
#define int long long 
using namespace std;

const int INF = 0x7fffffff;

struct Node {//treap
    Node *ch[2];
    int r;
    int v;
    int s;
    
    Node(int v):v(v){//建立新节点
        ch[0] = ch[1] = NULL;
        r = rand();
        s = 1;
        v = v;
    }
    
    bool operator<(const Node &a){//以优先级评定大小
        return r < a.r;
    }
    
    int cmp(int x) const{//寻找在左子树还是右子树或者是自己
        if(x == v)return -1;
        return (x < v ? 0 : 1);
    }
    
    void push_up(void){//调整附加信息s
        s = 1;
        if(ch[0] != NULL)s += ch[0] -> s;
        if(ch[1] != NULL)s += ch[1] -> s;
    }
};

Node* treap;

void rotate(Node* &o, int d){//旋转
    Node* k = o -> ch[d^1];
    o -> ch[d^1] = k -> ch[d];
    k -> ch[d] = o;
    o -> push_up(), k -> push_up();
    o = k;
}

void insert(Node* &o, int x){//插入
    if(o == NULL){
        o = new Node(x);
    }else{
        int d = o -> cmp(x);
        insert(o -> ch[d], x);
        if(o -> ch[d] > o){
            rotate(o, d^1);
        }
    }
    o -> push_up();
}

void remove(Node* &o, int x){//删除
    int d = o -> cmp(x);
    
    if(d == -1){
        if(o -> ch[0] == NULL){
            o = o -> ch[1];
        }else if(o -> ch[1] == NULL){
            o = o -> ch[0];
        }else{
            int dd = (o -> ch[0] > o -> ch[1] ? 0 : 1);
            rotate(o, dd);
            remove(o -> ch[dd], x);
        }
    }
    else{
        remove(o -> ch[d], x);
    }
    
    if(o != NULL) o -> push_up();
}

int find(Node* &o, int x){//寻找是否存在此节点
    while(o != NULL){
        int d = o -> cmp(x);
        if(d == -1)return 1;
        else o = o -> ch[d];
    }
    return 0;
}

int get_rank(Node* o, int k){//k排名的数
    if(o == NULL || k <= 0 || k > o -> s){
        return 0;
    }
    
    int s = (o -> ch[0] == NULL ? 0 : o -> ch[1] -> s);
    
    if(k == s+1) return o -> v;
    else if(k <= s) return get_rank(o -> ch[1], k);
    else return get_rank(o -> ch[0], k - s - 1);
}

int get_id(Node* o, int x){//x的排名
    if(o == NULL){
        return 1;
    }
    int d = o->cmp(x);
    if(d == 0)return get_id(o->ch[0],x);
    else return get_id(o -> ch[1],x)+o -> ch[0] -> s +1;
}

int get_pre(Node* o,int x){//前驱
    if(o == NULL)return -INF;
    
    int d = o->cmp(x);
    
    if(d == 1)return max(o -> v,get_pre(o -> ch[d],x));
    else return get_pre(o -> ch[d],x);
}

int get_nxt(Node* o,int x){//后继
    if(o == NULL)return INF;
    
    int d = o->cmp(x);
    
    if(d == 0)return min(o -> v,get_nxt(o -> ch[d],x));
    else return get_nxt(o -> ch[d],x);
}

signed main(){
    int n;
    treap = NULL;
    cin >> n;
    while(n --){//读入
        int opt,x;
        cin >> opt >> x;
        if(opt == 1){
           insert(treap,x); 
        }else if(opt == 2){
            remove(treap,x);
        }else if(opt == 3){
            cout << get_id(treap,x) << endl;
        }else if(opt == 4){
            cout << get_rank(treap,x) << endl;
        }else if(opt == 5){
            cout << get_pre(treap,x) << endl;
        }else{
            cout << get_nxt(treap,x) << endl;
        }
    }
    return 0;
}

手写 treap 求调

2023/8/29 11:54
加载中...