悬赏一个关注 88pts 最后一个点TLE求调
查看原帖
悬赏一个关注 88pts 最后一个点TLE求调
772999
jr_zch楼主2023/5/30 21:03
#include <bits/stdc++.h>
using namespace std;

const int maxn=1e5+7;
int n,m,cnt,x,root,op;
int a[maxn],dat[maxn<<1],siz[maxn<<1],f[maxn<<1],s[maxn<<1][2];

void link(int u,bool d,int v){
    s[u][d]=v,f[v]=u;
    return ;
}

void pushup(int u){
    siz[u]=1;
    if(s[u][0]) siz[u]+=siz[s[u][0]];
    if(s[u][1]) siz[u]+=siz[s[u][1]];
    return ;
}

void rotation(int now){
    int u=f[now],v=f[u];
    bool d=s[u][0]==now;
    link(u,d^1,s[now][d]),link(now,d,u),link(v,s[v][1]==u,now);
    pushup(u),pushup(now);
    return ;
}

void splay(int now,int top){
    while(f[now]!=top){
        int u=f[now],v=f[u];
        if(v!=top){
            if((s[u][0]==now)==(s[v][0]==u)) rotation(u); 
            else rotation(now); 
        }
        rotation(now);
    }
    if(top==0) root=now;
}

int find(int x){
    int now=root,d;
    while(now){
        if(x==dat[now]){
            splay(now,0);
            return now;
        }
        d=x>dat[now];
        if(s[now][d]) now=s[now][d];
        else break;
    }
    return -1;
}

int merge(int l,int r){
    if(!l||!r) return l+r;
    while(s[l][1]) l=s[l][1];
    splay(l,0),link(l,1,r),pushup(l);
    return l;
}

void insert(int x){
    int now=root,d;
    while(now){
        d=x>dat[now];
        if(s[now][d]) now=s[now][d];
        else break;
    }
    dat[++cnt]=x,siz[cnt]=1;
    if(now) link(now,d,cnt),pushup(now);
    splay(cnt,0);
    return ;
}

void delet(int x){
    int now=find(x);
    if(now==-1) return ;
    splay(now,0);
    f[s[now][0]]=f[s[now][1]]=0;
    root=merge(s[now][0],s[now][1]);
    return ;
}

int count(int x){
    int now=root,t=0;
    while(now){
        if(dat[now]<x) t+=siz[s[now][0]]+1,now=s[now][1];
        else now=s[now][0];
    }
    return t;
}

int kth(int x){
    int now=root,t;
    while(now){
        t=siz[s[now][0]]+1;
        if(x==t) break;
        if(x>t) x-=t,now=s[now][1];
        else now=s[now][0];
    }
    if(now) splay(now,0);
    return now;
}

int pre(int x){
	int now=root,p=0;
	while(now){
		if(dat[now]<x) p=now,now=s[now][1];
		else now=s[now][0];
	}
	if(p) splay(p,0);
	return p;
}

int nxt(int x){
	int now=root,p=0;
	while(now){
		if(dat[now]>x) p=now,now=s[now][0];
		else now=s[now][1];
	}
	if(p) splay(p,0);
	return p;
}

int main(){
    scanf("%d",&m);
    while(m--){
    	scanf("%d%d",&op,&x);
    	if(op==1) insert(x);
    	else if(op==2) delet(x);
    	else if(op==3) printf("%d\n",count(x)+1);
    	else if(op==4) printf("%d\n",dat[kth(x)]);
    	else if(op==5) printf("%d\n",dat[pre(x)]);
    	else printf("%d\n",dat[nxt(x)]);
	}
    return 0;
}
2023/5/30 21:03
加载中...