早就想在成都把$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; }