社区讨论

平衡树诡异的姿势,求卡。。。

学术版参与者 4已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@mi7wxvzv
此快照首次捕获于
2025/11/21 04:58
4 个月前
此快照最后确认于
2025/11/21 04:58
4 个月前
查看原帖
不会splay,就随便写了个东西。然后被卡了。发现并不平衡,就加了个随机提根233。
我觉得应该可以卡。
这是代码(肯定不对,但是我卡不掉)
CPP
#include<bits/stdc++.h>

using namespace std;

const int N=600010;

struct Node
{
    int siz,cnt,val;
    
    int child[2],fa;
}nd[N];
int cnt;
int root;

void update(int x)
{
    nd[x].siz=nd[nd[x].child[0]].siz+nd[nd[x].child[1]].siz+nd[x].cnt;
}

void rotate(int x)
{
    int fa=nd[x].fa,anc=nd[fa].fa;
    if(anc)
    {
        nd[anc].child[nd[anc].child[1]==fa]=x;
    }
    nd[x].fa=anc;
    bool idx=nd[fa].child[1]==x;
    nd[fa].child[idx]=nd[x].child[idx^1];
    nd[nd[x].child[idx^1]].fa=fa;
    nd[fa].fa=x;
    nd[x].child[idx^1]=fa;
    update(fa);
    update(x);
    if(!nd[x].fa) root=x;
}

void splay(int x,int goal)
{
    if(x==goal) return;
    while(nd[x].fa!=goal)
    {
        int fa=nd[x].fa,anc=nd[fa].fa;
        if(anc!=goal)
        {
            rotate(((nd[fa].child[0]==x)^(nd[anc].child[0]==fa))?x:fa);
        }
        rotate(x);
    }
}

void insert(int &x,int fa,int val)
{
    if(!x) 
    {
        x=++cnt;
        nd[x].val=val;
        nd[x].cnt=1;
        nd[x].siz=1;
        nd[x].fa=fa;
        splay(x,0);
        return;
    }
    if(val==nd[x].val) nd[x].cnt++,splay(x,0);
    else if(val<nd[x].val) insert(nd[x].child[0],x,val);
    else insert(nd[x].child[1],x,val);
}

int querymin(int x)
{
    int pre=0;
    for(;x;pre=x,x=nd[x].child[0]);
    return pre?nd[pre].val:0x7f7f7f7f;
}

int querymax(int x)
{
    int pre=0;
    for(;x;pre=x,x=nd[x].child[1]);
    return pre?nd[pre].val:0x8f8f8f8f;
}

int querypre(int now,int val)
{
    if(!now) return 0;
    if(val>querymin(nd[now].child[1])) return querypre(nd[now].child[1],val);
    else if(val>nd[now].val) return now;
    else return querypre(nd[now].child[0],val);
}

int querynxt(int now,int val)
{
    if(!now) return 0;
    if(val<querymax(nd[now].child[0])) return querynxt(nd[now].child[0],val);
    else if(val<nd[now].val) return now;
    else return querynxt(nd[now].child[1],val);
}

void remove(int val)
{
    int tmp=querynxt(root,val);
    splay(querypre(root,val),0);
    splay(tmp,root);
    int x=nd[tmp].child[0];
    if(nd[x].cnt>1) nd[x].cnt--;
    else nd[tmp].child[0]=0,nd[x].fa=0;
    update(x);
    update(tmp);
}

int querynum(int now,int rak)
{
    int lssiz=nd[nd[now].child[0]].siz;
    if(rak<=lssiz) return querynum(nd[now].child[0],rak);
    if(rak>lssiz+nd[now].cnt) return querynum(nd[now].child[1],rak-lssiz-nd[now].cnt);
    return nd[now].val;
}

int queryrank(int now,int val)
{
    if(!now) return 0;
    if(val==nd[now].val) return nd[nd[now].child[0]].siz+1;
    if(val>nd[now].val) return nd[nd[now].child[0]].siz+nd[now].cnt+queryrank(nd[now].child[1],val);
    else return queryrank(nd[now].child[0],val);
}

int main()
{
    srand(19260817);
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    insert(root,0,0x7f7f7f7f);
    insert(root,0,0x8f8f8f8f);
    int n;
    cin>>n;
    while(n--)
    {
        int opt,x;
        cin>>opt>>x;
        if(opt==1) insert(root,0,x);
        else if(opt==2) remove(x);
        else if(opt==3) cout<<queryrank(root,x)-1<<'\n';
        else if(opt==4) cout<<querynum(root,x+1)<<'\n';
        else if(opt==5) cout<<nd[querypre(root,x)].val<<'\n';
        else cout<<nd[querynxt(root,x)].val<<'\n';
        if (opt!=1) splay(rand()%cnt+1,0);
    }
}

回复

4 条回复,欢迎继续交流。

正在加载回复...