splay最后一个点被卡了
查看原帖
splay最后一个点被卡了
55211
LitDarkness楼主2021/2/13 14:45

rt
splay被卡了?还是我太菜了?
求助解决方法 提交记录

#include <bits/stdc++.h>
#define reg register

using namespace std;
const int maxN=100005,inf=2147483647;
template<typename T>inline void read(T& x){
    reg int f=0;
    x=0;
    char ch;
    while(!isdigit(ch=getchar()))f|=ch=='-';
    while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=f?-x:x;
}
char ch[20];
inline void write(int ans){
    reg int i=0;
    (ans<0)&&(ans=-ans,putchar('-'));
    ans||(putchar('0'));
    while(ans){
        ch[i++]=ans%10+48;
        ans/=10;
    }
    while(i)putchar(ch[--i]);
}
struct Splay{
	int v,fa,ch[2],sum,rec;
}t[maxN];
#define root t[0].ch[1]
int n,point;
void update(int x){t[x].sum=t[t[x].ch[0]].sum+t[t[x].ch[1]].sum+t[x].rec;}
int identify(int x){
    return t[t[x].fa].ch[0]==x?0:1;
}
void connect(int x,int f,int son){
    t[x].fa=f;t[f].ch[son]=x;
}
void rotate(int x){
    int y=t[x].fa;
    int mrt=t[y].fa,mrts=identify(y),ys=identify(x);
    int b=t[x].ch[ys^1];
    connect(b,y,ys);connect(y,x,ys^1);connect(x,mrt,mrts);
    update(y);update(x);
}
void splay(int at,int to){
    to=t[to].fa;
    while(t[at].fa!=to){
        int up=t[at].fa;
        if(t[up].fa==to)rotate(at);
        else if(identify(up)==identify(at)){
            rotate(up);rotate(at);
        }
        else{
            rotate(at);rotate(at);
        }
    }
}
int create(int v,int fa){
    ++n;
    t[n]={v,fa,{0,0},1,1};
    return n;
}
void destory(int x){
    t[x]={0,0,{0,0},0,0};
    if(x==n)--n;
}
int getroot(){
    return root;
}
int find(int v){
    int now=root;
    while(true){
        if(t[now].v==v){
            splay(now,root);
            return now;
        }
        int next=v<t[now].v?0:1;
        if(!t[now].ch[next])return 0;
        now=t[now].ch[next];
    }
}
int build(int v){
    ++point;
    if(n==0){
        root=1;
        create(v,0);
    }
    else {
        int now=root;
        while(true){
            ++t[now].sum;
            if(v==t[now].v){
                ++t[now].rec;
                return now;
            }
            int next=v<t[now].v?0:1;
            if(!t[now].ch[next]){
                create(v,now);
                t[now].ch[next]=n;
                return n;
            }
            now=t[now].ch[next];
        }
    }
    return 0;
}
void push(int v){
    int add=build(v);
    splay(add,root);
}
void pop(int v){
    int d=find(v);
    if(!d)return;
    --point;
    if(t[d].rec>1){
        --t[d].rec;
        t[d].sum--;
        return;
    }
    if(!t[d].ch[0]){
        root=t[d].ch[1];
        t[root].fa=0;
    }
    else{
        int lef=t[d].ch[0];
        while(t[lef].ch[1])lef=t[lef].ch[1];
        splay(lef,t[d].ch[0]);
        int rig=t[d].ch[1];
        connect(rig,lef,1);connect(lef,0,1);
        update(lef);
    }
    destory(d);
}
int _rank(int v){
    int ans=0,now=root;
    while(true){
        if(t[now].v==v)return ans+t[t[now].ch[0]].sum+1;
        if(now==0)return 0;
        if(v<t[now].v)now=t[now].ch[0];
        else{
            ans=ans+t[t[now].ch[0]].sum+t[now].rec;
            now=t[now].ch[1];
        }
    }
    if(now)splay(now,root);
    return 0;
}
int atrank(int x){
    if(x>point)return -inf;
    int now=root;
    while(true){
        int minused=t[now].sum-t[t[now].ch[1]].sum;
        if(x>t[t[now].ch[0]].sum&&x<=minused)break;
        if(x<minused)now=t[now].ch[0];
        else{
            x=x-minused;
            now=t[now].ch[1];
        }
    }
    splay(now,root);
    return t[now].v;
}
int upper(int v){
    int now=root;
    int result=inf;
    while(now){
        if(t[now].v>v&&t[now].v<result)result=t[now].v;
        if(v<t[now].v)now=t[now].ch[0];
        else now=t[now].ch[1];
    }
    return result;
}
int lower(int v){
    int now=root;
    int result=-inf;
    while(now){
        if(t[now].v<v&&t[now].v>result)result=t[now].v;
        if(v>t[now].v)now=t[now].ch[1];
        else now=t[now].ch[0];
    }
    return result;
}
#undef root
#define rd read
int q;
int main(){
    freopen("P3369_12.txt","r",stdin);
    freopen("output.out","w",stdout);
    push(-inf);
    push(inf);
    rd(q);
    while(q--){
        int x,v;
        rd(x);rd(v);
        switch(x){
            case 1:{
                push(v);
                break;
            }
            case 2:{
                pop(v);
                break;
            }
            case 3:{
                write(_rank(v)-1);
                putchar('\n');
                break;
            }
            case 4:{
                write(atrank(v+1));
                putchar('\n');
                break;
            }
            case 5:{
                write(lower(v));
                putchar('\n');
                break;
            }
            case 6:{
                write(upper(v));
                putchar('\n');
                break;
            }
        }
    }
    return 0;
}
2021/2/13 14:45
加载中...