我写的替罪羊树、Treap树和FHQ Treap树都有Bug,求调!!!
查看原帖
我写的替罪羊树、Treap树和FHQ Treap树都有Bug,求调!!!
1416993
dalu楼主2024/12/31 21:55

替罪羊树(AI调过:

#include <iostream>
#define N 1000010
#define alpha 0.75
using namespace std;

struct node{
    int ls,rs;
    int val;
    int tot;
    int size;
    int del;
}t[N];

int order[N],cnt;
int tree_stack[N],top = 0;
int root = 0;

void inorder(int u){
    if(!u) return;
    inorder(t[u].ls);
    if(t[u].del) order[++cnt] = u;
    else tree_stack[++top] = u;
    inorder(t[u].rs);
}

void Initnode(int u){
    t[u].ls = t[u].rs = 0;
    // FIXED
    t[u].size = t[u].tot = 1;
    t[u].del = 0;
}

void Update(int u){
    t[u].size = t[t[u].ls].size + t[t[u].rs].size + 1;
    t[u].tot = t[t[u].ls].tot + t[t[u].rs].tot + 1;
}

void build(int l,int r,int &u){
    int mid = (l + r) >> 1;
    u = order[mid];
    if(l == r){Initnode(u);return;}
    if(l < mid) build(l,mid - 1,t[u].ls);
    if(l == mid) t[u].ls = 0;
    build(mid + 1,r,t[u].rs);
    Update(u);
}

void rebuild(int &u){
    cnt = 0;
    inorder(u);
    if(cnt) build(1,cnt,u);
    else u = 0;
}

bool notbalance(int u){
    // if((double)t[u].size * alpha <= (double)max(t[t[u].ls].size,t[t[u].rs].size))
    //     return true;
    // return false;
    int left_size = t[t[u].ls].size;
    int right_size = t[t[u].rs].size;
    return (double)left_size > (double)t[u].size * alpha || (double)right_size > (double)t[u].size * alpha;
}

void Insert(int &u,int x){
    if(!u){
        u = tree_stack[top--];
        t[u].val = x;
        Initnode(u);
        return;
    }
    t[u].size++;
    t[u].tot++;
    if(t[u].val >= x) Insert(t[u].ls,x);
    else Insert(t[u].rs,x);
    if(notbalance(u)) rebuild(u);
}

int Rank(int u, int x) {
    if(u == 0) return 0;
    if(x > t[u].val) return t[t[u].ls].size + t[u].del + Rank(t[u].rs,x);
    return Rank(t[u].ls,x);
}

int kth(int k){
    int u = root;
    while(u){
        if(!t[u].del && t[t[u].ls].size + 1 == k) return t[u].val;
        else if(t[t[u].ls].size >= k) u = t[u].ls;
        else{
            // k -= t[t[u].ls].size + t[u].del;
            k -= t[t[u].ls].size + (t[u].del ? 1 : 0); // FIXED
            u = t[u].rs;
        }
    }
    return -1;
}


void Del_k(int &u,int k){
    t[u].size--;
    if(t[t[u].ls].size + 1 == k){
        t[u].del = 1;           // FIXED
        return;
    }
    if(t[t[u].ls].size + t[u].del >= k) Del_k(t[u].ls,k);
    else Del_k(t[u].rs,k - t[t[u].ls].size - t[u].del);
}

void Del(int x){
    Del_k(root,Rank(root,x) + 1);
    if(t[root].tot * alpha >= t[root].size) rebuild(root);
}

int predecessor(int u, int x) {
    int last = -1; // 用于存储前驱
    while (u) {
        if (t[u].val < x) {
            last = t[u].val; // 更新前驱
            u = t[u].rs; // 向右子树查找
        } else {
            u = t[u].ls; // 向左子树查找
        }
    }
    return last; // 返回前驱
}

int successor(int u, int x) {
    int last = -1; // 用于存储后继
    while (u) {
        if (t[u].val > x) {
            last = t[u].val; // 更新后继
            u = t[u].ls; // 向左子树查找
        } else {
            u = t[u].rs; // 向右子树查找
        }
    }
    return last; // 返回后继
}


int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr),cout.tie(nullptr);
    for(int i = N - 1;i >= 1;i--) tree_stack[++top] = i;
    int q;
    cin >> q;
    while(q--){
        int op,x;
        cin >> op >> x;
        switch(op){
        case 1:Insert(root,x);break;
        case 2:Del(x);break;
        case 3:cout << Rank(root,x) + 1 << '\n';break;
        case 4:cout << kth(x) << '\n';break;
        // case 5:cout << kth(Rank(root,x)) << '\n';break;
        // case 6:cout << kth(Rank(root,x + 1) + 1) << '\n';break;
        case 5: cout << predecessor(root, x) << '\n'; break; // 查询前驱
        case 6: cout << successor(root, x) << '\n'; break; // 查询后继

        }
    }
    return 0;
}

Treap树:

#include <iostream>
#include <ctime>
#define M 1000010
using namespace std;

int cnt = 0;

struct Node{
    int ls,rs;
    int key,pri;
    int size;
}t[M];

void newNode(int x){
    cnt++;
    t[cnt].size = 1;
    t[cnt].ls = t[cnt].rs = 0;
    t[cnt].key = x;
    t[cnt].pri = rand();
}

void Update(int u){
    t[u].size = t[t[u].ls].size + t[t[u].rs].size + 1;
}

void rotate(int &o,int d){
    int k;
    if(d == 1){
        k = t[o].rs;
        t[o].rs = t[k].ls;
        t[k].ls = o;
    }else{
        k = t[o].ls;
        t[o].ls = t[k].rs;
        t[k].rs = o;
    }
    t[k].size = t[o].size;
    Update(o);
    o = k;
}

void Insert(int &u,int x){
    if(u == 0){newNode(x);u = cnt;return;}
    t[u].size++;
    if(u >= t[u].key) Insert(t[u].rs,x);
    else Insert(t[u].ls,x);
    if(t[u].ls != 0 && t[u].pri > t[t[u].ls].pri) rotate(u,0);
    if(t[u].rs != 0 && t[u].pri > t[t[u].rs].pri) rotate(u,1);
    Update(u);
}

void Del(int &u,int x){
    t[u].size--;
    if(t[u].key == x){
        if(t[u].ls == 0 && t[u].rs == 0){u = 0;return;}
        if(t[u].ls == 0 || t[u].rs == 0){u = t[u].ls + t[u].rs;return;}
        if(t[t[u].ls].pri < t[t[u].rs].pri){rotate(u,0);Del(t[u].rs,x);return;}
        else{rotate(u,1);Del(t[u].ls,x);return;}
    }
    if(t[u].key >= x) Del(t[u].ls,x);
    else Del(t[u].rs,x);
    Update(u);
}

int Rank(int u,int x){
    if(u == 0) return 0;
    if(x > t[u].key) return t[t[u].ls].size + 1 + Rank(t[u].rs,x);
    return Rank(t[u].ls,x);
}

int kth(int u,int k){
    if(k == t[t[u].ls].size + 1) return t[u].key;
    if(k > t[t[u].ls].size + 1) return kth(t[u].rs,k - t[t[u].ls].size) - 1;
    if(k <= t[t[u].ls].size) return kth(t[u].ls,k);
    return 0;
}

int Precursor(int u,int x){
    if(u == 0) return 0;
    if(t[u].key >= x) return Precursor(t[u].ls,x);
    int tmp = Precursor(t[u].rs,x);
    if(tmp == 0) return t[u].key;
    return tmp;
}

int Succursor(int u,int x){
    if(u == 0) return 0;
    if(t[u].key <= x) return Succursor(t[u].rs,x);
    int tmp = Succursor(t[u].ls,x);
    if(tmp == 0) return t[u].key;
    return tmp;
}

int main(){
    srand(time(nullptr));
    int root = 0;
    int n;
    cin >> n;
    while(n--){
        int op,x;
        cin >> op >> x;
        switch(op){
        case 1:Insert(root,x);break;
        case 2:Del(root,x);break;
        case 3:cout << Rank(root,x) + 1 << '\n';break;
        case 4:cout << kth(root,x) << '\n';break;
        case 5:cout << Precursor(root,x) << '\n';break;
        case 6:cout << Succursor(root,x) << '\n';break;
        }
    }
    return 0;
}

FHQ Treap树:

#include <iostream>
#include <ctime>
#define M 1000010
using namespace std;

int cnt = 0,root = 0;

struct Node{
    int ls,rs;
    int key,pri;
    int size;
}t[M];

void newNode(int x){
    cnt++;
    t[cnt].size = 1;
    t[cnt].ls = t[cnt].rs = 0;
    t[cnt].key = x;
    t[cnt].pri = rand();
}

void Update(int u){
    t[u].size = t[t[u].ls].size + t[t[u].rs].size + 1;
}

void Split(int u,int x,int &L,int &R){
    if(u == 0){L = R = 0;return;}
    if(t[u].key <= x){
        L = u;
        Split(t[u].rs,x,t[u].rs,R);
    }else{
        R = u;
        Split(t[u].ls,x,L,t[u].ls);
    }
    Update(u);
}

int Merge(int L,int R){
    if(L == 0 || R == 0) return L + R;
    if(t[L].pri > t[R].pri){
        t[L].rs = Merge(t[L].rs,R);
        Update(L);
        return L;
    }else{
        t[R].ls = Merge(L,t[R].ls);
        Update(R);
        return R;
    }
}

void Insert(int x){
    int L,R;
    Split(root,x,L,R);
    newNode(x);
    int aa = Merge(L,cnt);
    root = Merge(aa,R);
}

void Del(int x){
    int L,R,p;
    Split(root,x,L,R);
    Split(L,x - 1,L,p);
    p = Merge(t[p].ls,t[p].rs);
    root = Merge(Merge(L,p),R);
}

void Rank(int x){
    int L,R;
    Split(root,x - 1,L,R);
    cout << t[L].size + 1 << '\n';
    root = Merge(L,R);
}

int kth(int u,int k){
    if(k == t[t[u].ls].size + 1) return u;
    if(k > t[t[u].ls].size + 1) return kth(t[u].ls,k);
    if(k <= t[t[u].ls].size) return kth(t[u].rs,k - t[t[u].ls].size - 1);
    return 0;
}

void Precursor(int x){
    int L,R;
    Split(root,x - 1,L,R);
    cout << t[kth(L,t[L].size)].key << '\n';
    root = Merge(L,R);
}

void Succursor(int x){
    int L,R;
    Split(root,x,L,R);
    cout << t[kth(R,1)].key << '\n';
    root = Merge(L,R);
}

int main(){
    srand(time(nullptr));
    int n;
    cin >> n;
    while(n--){
        int op,x;
        cin >> op >> x;
        switch(op){
        case 1:Insert(x);break;
        case 2:Del(x);break;
        case 3:Rank(x);break;
        case 4:cout << t[kth(root,x)].key << '\n';break;
        case 5:Precursor(x);break;
        case 6:Succursor(x);break;
        }
    }
    return 0;
}
2024/12/31 21:55
加载中...