Splay球调

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

曹操废了 @ 2022-04-27 19:40:03

RT,输入输出改一下原版就能过了,但是这题样例没过去(

#include<iostream>
#include<cstdio>
#define MAXN 100001
#define INF 0x3f3f3f3f
#define root tree[0].ch[1]
#define ls(x) tree[x].ch[0]
#define rs(x) tree[x].ch[1]
#define fa(x) tree[x].fa
using namespace std;
struct node{
    int val;//权值
    int fa;//父亲节点
    int ch[2];//0代表左儿子,1代表右儿子
    int rec;//这个权值的节点出现的次数
    int sum;//子节点的数量
}tree[MAXN];
int tot=0,pointnum=0;
int n,m,ans114514;
bool ident(int x){//判断当前结点是左孩子,还是右孩子。0为左孩子,1为右孩子
    return tree[fa(x)].ch[0]==x?0:1;
}//
void connect(int x,int fa,int how){//x节点将成为fa节点的how孩子
    tree[x].fa=fa;
    tree[fa].ch[how]=x;
}//
void update(int x){
    tree[x].sum=tree[ls(x)].sum+tree[rs(x)].sum+tree[x].rec;
}//
void rotate(int x){//单旋
    int Y=fa(x);
    int R=fa(Y);
    int Yson=ident(x);
    int Rson=ident(Y);
    connect(tree[x].ch[Yson^1],Y,Yson);
    connect(Y,x,Yson^1);
    connect(x,R,Rson);
    update(Y);
    update(x);
}//
void Splay(int x,int to){//双旋
    to=fa(to);
    while(fa(x)!=to){
        int y=fa(x);
        if(tree[y].fa==to) rotate(x);
        else if(ident(x)==ident(y)) rotate(y),rotate(x);
        else rotate(x),rotate(x);
    }
}//
int newpoint(int v,int f){//插入
    tree[++tot].fa=f;
    tree[tot].val=v;
    tree[tot].sum=tree[tot].rec=1;
    return tot;
}
void Insert(int x){//插入
    int now=root;
    if(root==0){
        newpoint(x,0);
        root=tot;
    }else{
        while(1){
            tree[now].sum++;
            if(tree[now].val==x){
                tree[now].rec++;
                Splay(now,root);
                return ;
            }
            int nxt=x<tree[now].val?0:1;
            if(!tree[now].ch[nxt]){
                int p=newpoint(x,now);
                tree[now].ch[nxt]=p;
                Splay(p,root);
                return ;
            }
            now=tree[now].ch[nxt];
        }
    }
}//
int find(int v){//查询位置
    int now=root;
    while(1){
        if(!now) return 0;
        if(tree[now].val==v){
            Splay(now,root);
            return now;
        }
        int nxt=v<tree[now].val?0:1;
        now=tree[now].ch[nxt];
    }
}//
void dele(int x){//删除
    int pos=find(x);
    if(!pos) return ;
    if(tree[pos].rec>1){
        tree[pos].rec--;
        tree[pos].sum--;
        return ;
    }
    else{
        if(!tree[pos].ch[0]&&!tree[pos].ch[1]){
            root=0;
            return ;
        }
        else if(!tree[pos].ch[0]){
            root=tree[pos].ch[1];
            tree[root].fa=0;
            return ;
        }
        else{
            int left=tree[pos].ch[0];
            while(tree[left].ch[1]) left=tree[left].ch[1];
            Splay(left,tree[pos].ch[0]);
            connect(tree[pos].ch[1],left,1);
            connect(left,0,1);
            update(left);
        }
    }
}//
int rak(int v){// 查询值为v的数的排名
    int pos=find(v);
    return tree[ls(pos)].sum+1;
}
int arank(int x){//查询排名为x的数是什么 
    int now=root;
    while(1){
        int used=tree[now].sum-tree[tree[now].ch[1]].sum;
        if(x>tree[tree[now].ch[0]].sum&&x<=used) break;
        if(x<used) now=tree[now].ch[0];
        else x=x-used,now=tree[now].ch[1];
    }
    Splay(now,root);
    return tree[now].val;
}
int lower(int v){//查询v的前驱
    int now=root;
    int ans=-INF;
    while(now){
        if(tree[now].val<v&&tree[now].val>ans) ans=tree[now].val;
        if(v>tree[now].val) now=tree[now].ch[1];
        else now=tree[now].ch[0];
    }
    return ans;
}
int upper(int v){//查询v的后继
    int now=root;
    int ans=INF;
    while(now){
        if(tree[now].val>v&&tree[now].val<ans) ans=tree[now].val;
        if(v<tree[now].val) now=tree[now].ch[0];
        else now=tree[now].ch[1];
    }
    return ans;
}
int opt,x,last;
int main(){
    cin>>n>>m;
    for(int i=1,u;i<=n;i++){
        cin>>u;
        Insert(u);
    }
    for(int i=1;i<=m;i++){
        cin>>opt>>x;
        x^=last;
        if(opt==1){
            Insert(x);
        }
        if(opt==2){
            dele(x);
        }
        if(opt<=2) continue;
        if(opt==3){
            last=rak(x);
        }
        if(opt==4){
            last=arank(x);
        }
        if(opt==5){
            last=lower(x);
        }
        if(opt==6){
            last=upper(x);
        }
        ans114514^=last;
        //cout<<ans114514<<"\n";
    }
    cout<<ans114514;
    return 0;
}

by 曹操废了 @ 2022-04-27 19:56:12

是我傻了,没注意到

查询排名为 x 的数(如果不存在,则认为是排名小于 x 的最大数。保证 x 不会超过当前数据结构中数的总数)。


by 曹操废了 @ 2022-04-27 20:00:46

这,这不对吧,这也不影响吧


|