萌新第一次接触OI,Splay求条
查看原帖
萌新第一次接触OI,Splay求条
1000298
Vsinger_洛天依楼主2023/10/31 10:38

已经用Treap A过这道题了,但是用Splay再打直接TLE了QAQ

#include<bits/stdc++.h>
#define lC q<<1
#define rC q<<1|1
#define int long long
#define INF 0x66ccff0712
#define endl "\n"
#define maxm 0x66ccff
#define maxn 0x6cf 
#define mid ((l+r)>>1)
#define void inline void
using namespace std;
inline int read(){
 int s = 0,w = 1;char ch = getchar();
 while(ch<'0'||ch>'9'){ if(ch == '-') w = -1;ch = getchar();}
 while(ch>='0'&&ch<='9'){ s = s*10+ch-'0';ch = getchar();}
 return s*w;
}
using namespace std;
struct SegmntTree{
    int f,key,ch[2],cnt,siz;
}t[maxm]; 
int sz;
int root;
void clear(int x){
    t[x].ch[1]=t[x].ch[2]=t[x].f=t[x].cnt=t[x].key=t[x].siz=0;
}
inline bool get(int x){
    return t[t[x].f].ch[2]==x;;
}
void update(int x){
    if(x){
        t[x].siz=t[x].cnt;
        if(t[x].ch[1])
            t[x].siz+=t[t[x].ch[1]].siz;
        if(t[x].ch[2])
            t[x].siz+=t[t[x].ch[2]].siz;
    }
}
void rotate(int x){
    int old=t[x].f,oldf=t[x].f,which=get(x);
    t[old].ch[which+1]=t[old].ch[(which^1)+1];
    t[t[old].ch[which+1]].f=old;
    t[x].ch[(which^1)+1]=old;
    t[old].f=x;
    t[x].f=oldf;
    if(oldf)
        t[oldf].ch[t[oldf].ch[1]==old]=x;
    update(old);
    update(x);
}
void splay(int x){
    for(int fa;fa=t[x].f;rotate(x)){
        if(t[fa].f)
            rotate(get(x)==get(fa)?fa:x);
    }
    root=x;
}
void insert(int v){
    if(root==0){
        sz++;
        root=sz;
        t[root].ch[1]=t[root].ch[2]=t[root].f=0;
        t[root].key=v;
        t[root].cnt=t[root].siz=1;
        return;
    }
    int cur=root,fa=0;
    while(1){
        if(t[cur].key==v){
            ++t[cur].cnt;
            update(cur);
            update(fa);
            splay(cur);
        }
        fa=cur;
        cur=t[cur].ch[(t[cur].key<v)+1];
        if(cur==0){
            ++sz;
            t[sz].ch[1]=t[sz].ch[2]=0;
            t[sz].key=v;
            t[sz].siz=1;
            t[sz].cnt=1;
            t[sz].f=fa;
            t[fa].ch[(t[fa].key<v)+1];
            update(fa);
            splay(sz);
        }
    }
}
inline int find(int v){
    int ans=0,cur=root;
    while(true){
        if(v<t[cur].key){
            cur=t[cur].ch[1];
        }
        else{
            ans+=(t[cur].ch[1]?t[t[cur].ch[1]].siz:0);
            if(v==t[cur].key){
                splay(cur);
                return ans+1;
            }
            ans+=t[cur].cnt;
            cur=t[cur].ch[2];
        }
    }
}

inline int Rank(int k){
    int cur=root;
    while(true){
        if(t[cur].ch[1]&&k<=t[t[cur].ch[0]].siz)
            cur=t[cur].ch[1];
        else{
            int tem=(t[cur].ch[1]?t[t[cur].ch[1]].siz:0)+t[cur].cnt;
            if(cur<=tem){
                return t[cur].key;
            }
            k-=tem;
            cur=t[cur].ch[2];
        }
    }
}

inline int pre(){
    int cur=t[root].ch[1];
    while(t[cur].ch[2])
        cur=t[cur].ch[2];
    return cur;
}


inline int nxt(){
    int cur=t[root].ch[2];
    while(t[cur].ch[0])
        cur=t[cur].ch[0];
    return cur;
}

void del(int v){
    find(v);
    if(t[root].cnt>1){
        t[root].cnt--;
        update(root);
        return;
    }
    if(!t[root].ch[1]&&!t[root].ch[2]){
        clear(root);
        root=0;
        sz=0;
        return;
    }
    if(!t[root].ch[1]){
        int oldroot=root;
        root=t[root].ch[2];
        t[root].f=0;
        clear(oldroot);
        return;
    }
    if(!t[root].ch[2]){
        int oldroot=root;
        root=t[root].ch[1];
        t[root].f=0;
        clear(oldroot);
        return;
    }
    int lpre=pre(),oldroot=root;
    splay(lpre);
    t[t[oldroot].ch[2]].f=root;
    t[root].ch[2]=t[oldroot].ch[2];
    clear(oldroot);
    update(root);
    return;
}
signed main(){
    int n=read();
	for(int i=1;i<=n;++i){
        int op=read(),x=read();
		switch(op){
			case 1:{
				insert(x);
				break;
			}
			case 2:{
				del(x);
				break;
			} 
			case 3:{
				printf("%d\n",find(x));
				break;
			}
			case 4:{
				printf("%d\n",Rank(x));
				break;
			}
			case 5:{
				insert(x);
				printf("%d\n",t[pre()].key);
				del(x);
				break;
			}
			case 6:{
				insert(x);
				printf("%d\n",t[nxt()].key);
				del(x);
				break;
			}
		}
	}
}
2023/10/31 10:38
加载中...