早就想在成都把$splay$改成指针打法了。当时竟然没调出来。指针真难调。早上重新打了一遍,改过来了。
其实是为了打$lct$的。指针感觉会快,喵喵喵?
普通平衡树模板:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define N 101000
#define lc(x) (x->ch[0])
#define rc(x) (x->ch[1])
#define fa(x) (x->fa)
#define size(x) (x->size)
struct Splay{
Splay *ch[2],*fa;
int size,w,v;
Splay(int x=0){ch[0]=ch[1]=fa=NULL;size=w=1;v=x;}
}*null,*root;
void init(){
null=new Splay(0);
lc(null)=rc(null)=fa(null)=null;null->size=null->w=0;
root=null;
}
bool get(Splay *rt){return rc(rt->fa)==rt;}
void update(Splay *rt){if(rt) rt->size=size(lc(rt))+size(rc(rt))+rt->w;}
Splay *xin(Splay *fa,int x){
Splay *now=new Splay(x);
lc(now)=rc(now)=null;fa(now)=fa;
if(fa!=null){
fa->ch[fa->v < x]=now;
update(fa);
}
return now;
}
void rotate(Splay *&rt){
Splay *old=fa(rt),*oldf=fa(old);
int d=get(rt);
Splay *t=rt;old->ch[d]=t->ch[d^1];old->ch[d]->fa=old;
t->ch[d^1]=old;old->fa=t;t->fa=oldf;
if(oldf!=null) oldf->ch[rc(oldf)==old]=t;
update(old);update(t);
rt=t;
}
void splay(Splay *rt){
for(Splay *fa;(fa=fa(rt))!=null;rotate(rt)){
if(fa(fa)!=null) rotate((get(rt)==get(fa))?fa:rt);
}
root=rt;
}
void insert(Splay *&rt,Splay *fa,int x){
if(rt==null){
rt=xin(fa,x);splay(rt);
return;
}
if(rt->v==x){
rt->w++;update(rt);splay(rt);return;
}
int d=rt->v < x;
insert(rt->ch[d],rt,x);
}
int pai(Splay *rt,int x){
if(rt==null) return 0;
if(x>rt->v) return size(lc(rt))+rt->w+pai(rc(rt),x);
else if(x==rt->v){
int ans=size(lc(rt))+1;splay(rt);
return ans;;
}
else return pai(lc(rt),x);
}
int kth(Splay *rt,int k){
if(k<=size(lc(rt))) return kth(lc(rt),k);
else{
int temp=size(lc(rt))+rt->w;
if(k<=temp) return rt->v;
else return kth(rc(rt),k-temp);
}
}
Splay *pre(){
Splay *now=lc(root);
while(rc(now)!=null) now=rc(now);
return now;
}
Splay *next(){
Splay *now=rc(root);
while(lc(now)!=null) now=lc(now);
return now;
}
void del(int x){
int whatever=pai(root,x);
if(root->w>1){root->w--;update(root);return;}
if(lc(root)==null&&rc(root)==null){root=null;return;}
if(lc(root)==null){Splay *t=rc(root);delete root;root=t;root->fa=null;return;}
if(rc(root)==null){Splay *t=lc(root);delete root;root=t;root->fa=null;return;}
Splay *leftbig=pre(),*oldroot=root,*t=rc(oldroot);
splay(leftbig);rc(root)=t;delete oldroot;fa(t)=root;
update(root);
}
void dfs(Splay *rt){
if(rt==null) return;
cout<<rt->v<<endl;
dfs(lc(rt));dfs(rc(rt));
}
int main(){
init();
int n,opt,x;
scanf("%d",&n);
for (int i=1;i<=n;++i){
scanf("%d%d",&opt,&x);
switch(opt){
case 1: insert(root,null,x); break;
case 2: del(x); break;
case 3: printf("%d\n",pai(root,x)); break;
case 4: printf("%d\n",kth(root,x)); break;
case 5: insert(root,null,x); printf("%d\n",pre()->v); del(x); break;
case 6: insert(root,null,x); printf("%d\n",next()->v); del(x); break;
}
}
return 0;
}