悬3关。萌新弱弱地问一句,咋错的?(Treap)
查看原帖
悬3关。萌新弱弱地问一句,咋错的?(Treap)
405146
Ruan_ji楼主2024/8/27 11:09

萌新写的Treap树挂掉了,86pts,前两个点WA,后面都AC了。

请求大佬看看细节有没有写错。

大佬们可以主要看看Insert函数和build函数和zig zag还有getrank函数。这里萌新下载了第一组测试用例供大佬们参考

sample1:

intput:

4
1 10
1 30
1 20
3 21

Ture output:

3

My output:

2

小句蒻第一次学,代码根lyd大佬的差不多,实在是见笑了。

码风良好,注释很全。

Code:

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>

#define MAXN 10000005

using namespace std;

struct treap{
    int l,r;
    int val, typ; //关键码,随机生成的权值
    int cnt,siz; //重复的次数,子树的大小
};
treap num[MAXN];

int n;

int tot; //标记的节点编号
int root,INF=0x7fffffff;

int New(int val){ //新建节点
    num[++tot].val=val;
    num[tot].typ=rand();
    num[tot].cnt=1;
    num[tot].siz=1;
    return tot;
}

void update(int u){ //更新子树的大小
    num[u].siz=num[num[u].l].siz+num[num[u].r].siz+num[u].cnt;
}

void build(){
    New(-INF); New(INF);
    root=1;
    num[1].r=2;
    update(root);
    return ;
}

int getval(int u,int rank){ //根据排名得知数值
    if(u==0) return INF;
    if(num[num[u].l].siz >= rank) {
        return getval(num[u].l,rank);
    }
    if(num[num[u].l].siz+num[u].cnt>=rank) {
        return num[u].val;
    }
    return getval(num[u].r,rank-num[num[u].l].siz-num[u].cnt);
}

int getrank(int u,int val){
    if(u==0) return 0;
    if(val==num[u].val){
        return num[num[u].l].siz+1;
    }
    if(val<num[u].val){
        return getrank(num[u].l, val);
    }
    return getrank(num[u].r,val)+num[num[u].l].siz+num[u].cnt;
}

void zagg(int &u){ //左旋
    int v=num[u].r;
    num[u].r=num[v].l;
    num[v].l=u;
    u=v;
    update(num[u].l);update(u);
}

void zigg(int &u){ //右旋
    int v=num[u].l;
    num[u].l=num[v].r;
    num[v].r=u;
    u=v;
    update(num[u].r); update(u);
    return ;
}

void Insert(int &u, int val){
    if(u==0){
        u=New(val);
        return ;
    }
    if(val==num[u].val) {
        num[u].cnt+=1;
        update(u);
        return ;
    }
    if(val < num[u].val){
        Insert(num[u].l,val);
        if(num[u].typ < num[num[u].l].typ){
            zigg(u);
        }
    }
    else{
        Insert(num[u].r,val);
        if(num[u].typ < num[num[u].r].typ){
            zagg(u);
        }
    }
    update(u);
}

int getpre(int val){
    int ans=1;
    int u=root;
    while(u){
        if(val==num[u].val){
            if(num[u].l>0){
                u=num[u].l;
                while(num[u].r>0){
                    u=num[u].r;
                }
                ans=u;
            }
            break;
        }
        if(num[u].val<val && num[u].val>num[ans].val){
            ans=u;
        }
        if(val<num[u].val){
            u=num[u].l;
        }
        else u=num[u].r;
    }

    return num[ans].val;
}

int getsuc(int val){
    int ans=2;
    int u=root;
    while(u){
        if(val==num[u].val){
            if(num[u].r>0){
                u=num[u].r;
                while(num[u].l>0){
                    u=num[u].l;
                }
                ans=u;
            }
            break;
        }
        if(num[u].val>val && num[u].val<num[ans].val){
            ans=u;
        }
        if(val<num[u].val){
            u=num[u].l;
        }
        else {
            u=num[u].r;
        }
    }

    return num[ans].val;
}

void del(int &u,int val){
    if(u==0){
        return ;
    }
    if (val==num[u].val){
        if(num[u].cnt>1){
            num[u].cnt-=1;
            update(u);
            return ;
        }
        if(num[u].l || num[u].r) {
            if(num[u].r==0||num[num[u].l].typ>num[num[u].r].typ){
                zigg(u);
                del(num[u].r,val);
            }
            else {
                zagg(u);
                del(num[u].l,val);
            }
            update(u);
        }
        else u=0;
        return ;
    }

    if(val<num[u].val){
        del(num[u].l,val);
    }
    else {
        del(num[u].r,val);
    }
    update(u);
}

int main(){
    build();
    scanf("%d", &n);
    for(int i=1;i<=n;++i){
        int opt,x;
        scanf("%d%d",&opt,&x);
        if(opt==1){
            Insert(root,x);
        }
        if(opt==2){
            del(root,x);
        }
        if(opt==3){
            printf("%d\n",getrank(root, x)-1);
        }
        if(opt==4){
            printf("%d\n",getval(root, x+1));
        }
        if(opt==5){
            printf("%d\n",getpre(x));
        }
        if(opt==6){
            printf("%d\n",getsuc(x));
        }
    }
    return 0;
}

大佬帮忙看看再走吧!小橘蒻会永远记得恩人的!

2024/8/27 11:09
加载中...