平衡树模板52求助

P6136 【模板】普通平衡树(数据加强版)

Cure_Wing @ 2022-08-25 20:11:04

正如题目所说的那样:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stdlib.h>
#define int long long
using std::cin;using std::cout;
constexpr int N=1e6+19,inf=0x7fffffff;
int last,na,m,ch[N][2],val[N],dat[N],size[N],cnt[N],tot,root,ans;
int New(int v){
    val[++tot]=v;
    dat[tot]=rand();
    size[tot]=1;
    cnt[tot]=1;
    return tot;
}
void pushup(int id){
    size[id]=size[ch[id][0]]+size[ch[id][1]]+cnt[id];
}
void build(){
    root=New(-inf),ch[root][1]=New(inf);
    pushup(root);
}
void rotate(int &id,int d){
    int temp=ch[id][d^1];
    ch[id][d^1]=ch[temp][d];
    ch[temp][d]=id;
    id=temp;
    pushup(ch[id][d]),pushup(id);
}
void insert(int &id,int v){
    if(!id) return id=New(v),void();
    if(v==val[id]) ++cnt[id];
    else{
        int d=v<val[id]?0:1;
        insert(ch[id][d],v);
        if(dat[id]<dat[ch[id][d]]) rotate(id,d^1);
    } 
    pushup(id);
}
void remove(int &id,int v){
    if(!id) return ;
    if(v==val[id]){
        if(cnt[id]>1) return --cnt[id],pushup(id),void();
        if(ch[id][0]||ch[id][1]){
            if(!ch[id][1]||dat[ch[id][0]]>dat[ch[id][1]]) rotate(id,1),remove(ch[id][1],v);
            else rotate(id,0),remove(ch[id][0],v);
            pushup(id);
        }else id=0;
        return ;
    }
    v<val[id]?remove(ch[id][0],v):remove(ch[id][1],v);
    pushup(id);
}
int get_rank(int id,int v){
    if(!id) return 0;
    if(v==val[id]) return size[ch[id][0]]+1;
    if(v<val[id]) return get_rank(ch[id][0],v);
    return size[ch[id][0]]+cnt[id]+get_rank(ch[id][1],v);
}
int get_val(int id,int rank){
    if(!id) return inf;
    if(rank<=size[ch[id][0]]) return get_val(ch[id][0],rank);
    if(rank<=size[ch[id][0]]+cnt[id]) return val[id];
    return get_val(ch[id][1],rank-size[ch[id][0]]-cnt[id]);
}
int get_pre(int v){
    int id=root,pre;
    while(id){
        if(val[id]<v) pre=val[id],id=ch[id][1];
        else id=ch[id][0];
    }
    return pre;
}
int get_next(int v){
    int id=root,next;
    while(id){
        if(val[id]>v) next=val[id],id=ch[id][0];
        else id=ch[id][1];
    }
    return next;
}
signed main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
//  srand((unsigned)time(0));
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    build();
    cin>>na>>m;
    for(int i=1;i<=na;++i){
        int x;
        cin>>x;
        insert(root,x);
    }
    for(int i=1;i<=m;++i){
        int cmd,x;
        cin>>cmd>>x;
        x^=last;
//      cout<<cmd<<' '<<x<<'\n';
        if(cmd==1) insert(root,x);
        else if(cmd==2) remove(root,x);
        else if(cmd==3) ans^=(last=(get_rank(root,x)-1));
        else if(cmd==4) ans^=(last=get_val(root,x+1));
        else if(cmd==5) ans^=(last=get_pre(x));
        else ans^=(last=get_next(x));
//      cout<<last<<'\n';
    }
    cout<<ans;
    return 0;
}
//52

by Cure_Wing @ 2022-08-28 20:09:53

@youdu666 @LYS_AK_IOI


by Cure_Wing @ 2022-08-28 20:20:55

已过。如果访问的数不存在插入一下再删除就好了。

else if(cmd==3) insert(root,x),ans^=(last=get_rank(root,x)-1),remove(root,x);

by C_liar @ 2022-09-13 10:48:40

@Dragon_Horse 我的天,谢神犇!!!调了两天!我和您错误一样! Orz Orz Orz


|