splay TLE 求条(玄关)
查看原帖
splay TLE 求条(玄关)
752441
CuFeO4楼主2024/3/16 18:31
#include<bits/stdc++.h>
using namespace std;
#define pc putchar
#define pt puts("")
using ll=long long;
namespace IO{
    #define int long long
    inline int read(){
        int x=0;char s=getchar_unlocked();bool f=true;
        for(;s<'0'||'9'<s;s=getchar_unlocked()) if(s=='-') f=false;
        for(;'0'<=s&&s<='9';s=getchar_unlocked()) x=(x<<1)+(x<<3)+(s^48);
        return f?x:~x+1;}
    #define read read()
    #undef int
    template<typename T> 
    inline void write(T x){
        static T st[45];T top=0;if(x<0)x=~x+1,putchar('-');
        do{st[top++]=x%10;}while(x/=10);while(top)putchar(st[--top]^48);
    }
}using namespace IO;
const int N=1e5+10;
namespace Splay{
    int root,tot;
    struct Splay{
        int size,fa,cnt,ch[2];
        ll val;
        #define size(x) tree[x].size
        #define val(x) tree[x].val
        #define fa(x) tree[x].fa
        #define cnt(x) tree[x].cnt
        #define ls(x) tree[x].ch[0]
        #define rs(x) tree[x].ch[1]
        #define ch(x,y) tree[x].ch[y]
    }tree[N];
    inline auto pushup(int x){
        size(x)=size(ls(x))+size(rs(x))+cnt(x);
    }
    inline auto get(int x){
        return x==rs(fa(x));
    }
    inline auto clear(int x){
        size(x)=val(x)=fa(x)=cnt(x)=ls(x)=rs(x)=0;
    }
    inline auto rotate(int x){
        int y=fa(x),z=fa(y),chk=get(x);
        if(z) ch(z,get(y))=x;
        fa(x)=z;
        ch(y,chk)=ch(x,chk^1);fa(ch(x,chk^1))=y;
        ch(x,chk^1)=y;fa(y)=x;
        pushup(y);pushup(x);
    }
    inline auto splay(int x,int goal=0){
        while(fa(x)!=goal){
            int y=fa(x),z=fa(y);
            if(z!=goal) rotate(get(x)==get(y)?y:x);
            rotate(x);
        }
        if(!goal) root=x;
    }
    inline auto insert(ll val){
        int x=root,f=0;
        while(x&&val(x)!=val) f=x,x=ch(x,val(x)<val);
        if(x) ++cnt(x);
        else{
            x=++tot;
            fa(x)=f;val(x)=val;
            size(x)=cnt(x)=1;
            ls(x)=rs(x)=0;
            if(f) ch(f,val(f)<val)=x;
        }
        splay(x);
    }
    inline auto find(ll val){
        int x=root;
        while(ch(x,val(x)<val)&&val(x)!=val) x=ch(x,val(x)<val);
        splay(x);
    }
    inline auto pre_nxt(ll val,bool flag){
        find(val);
        int x=root;
        if(val(x)<val&&!flag) return x;
        if(val(x)>val&&flag) return x;
        x=ch(x,flag);
        while(ch(x,flag^1)) x=ch(x,flag^1);
        return x;
    }
    inline auto rnk(ll val){
        int x=pre_nxt(val,0);
        splay(x);
        return size(ch(x,0))+cnt(x)+1;
    }
    inline auto kth(int k){
        int x=root;
        while(true){
            if(k<=size(ch(x,0))) x=ch(x,0);
            else if(k<=size(ch(x,0))+cnt(x)) return val(x);
            else k-=size(ch(x,0))+cnt(x),x=ch(x,1);
        }
    }
    inline auto del(ll val){
        int pre=pre_nxt(val,0),nxt=pre_nxt(val,1);
        splay(pre);splay(nxt,pre);
        int x=ch(nxt,0);
        if(cnt(x)>1){
            cnt(x)--;
            splay(x);
        }
        else clear(x);
    }
}using namespace Splay;
signed main(){
    #ifndef ONLINE_JUDGE
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
    int n=read;
    insert(INT_MAX);
    insert(-INT_MAX);
    for(int i=1;i<=n;++i){
        // cerr<<i<<'\n';
        int op=read,x=read;
        switch(op){
            case 1:insert(x); break;
            case 2:del(x); break;
            case 3:write(rnk(x)-1);pt; break;
            case 4:write(kth(x+1));pt; break;
            case 5:write(tree[pre_nxt(x,0)].val);pt; break;
            case 6:write(tree[pre_nxt(x,1)].val);pt; break;
        }
    }
}
2024/3/16 18:31
加载中...