借着这道题贴一下splay的模板,自己的splay是照着油田的ZYF学的,跟她写的差不多,但是好慢(不要被dalao看到),不过其实蛮精炼的(什么鬼),感觉没有那么多的废话,贴代码跑
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
const int N=100010;
int n;
inline int F()
{
register int aa,bb;register char ch;
while(ch=getchar(),ch!='-'&&(ch>'9'||ch<'0'));ch=='-'?aa=bb=0:(aa=ch-'0',bb=1);
while(ch=getchar(),ch>='0'&&ch<='9')aa=(aa<<3)+(aa<<1)+ch-'0';return bb?aa:-aa;
}
struct SplayTree{
int ch[N][2],f[N],size[N],cnt[N],key[N];
int sz,root;
inline void clear(int x){ch[x][1]=ch[x][0]=size[x]=f[x]=key[x]=cnt[x]=0;}
inline bool get(int x){return ch[f[x]][1]==x;}
inline void updata(int x)
{
if (x)
{
size[x]=cnt[x];
if (ch[x][0])size[x]+=size[ch[x][0]];
if (ch[x][1])size[x]+=size[ch[x][1]];
}
}
inline void rotate(int x)
{
int old=f[x],oldf=f[old],which=get(x);
ch[old][which]=ch[x][which^1];f[ch[old][which]]=old;
f[old]=x;ch[x][which^1]=old;f[x]=oldf;
if (oldf)
ch[oldf][ch[oldf][1]==old]=x;
updata(x);updata(old);
}
inline void splay(int x)
{
for (int fa;(fa=f[x]);rotate(x))
if (f[fa])rotate((get(x)==get(fa))?fa:x);
root=x;
}
inline void insert(int v)
{
if (root==0)
{
sz++;ch[sz][0]=ch[sz][1]=f[sz]=0;
key[sz]=v;size[sz]=1;cnt[sz]=1;
root=sz;return;
}
int now=root,fa=0;
while(1)
{
if (key[now]==v)
{
cnt[now]++;updata(now);updata(fa);
splay(now);break;
}
fa=now;now=ch[now][key[now]<v];
if (now==0)
{
sz++;
ch[sz][0]=ch[sz][1]=0;key[sz]=v;
size[sz]=1;cnt[sz]=1;f[sz]=fa;
ch[fa][key[fa]<v]=sz;
updata(fa);splay(sz);break;
}
}
}
inline int find(int v)
{
int ans=0,now=root;
while(1)
{
if (v<key[now])now=ch[now][0];
else
{
ans+=(ch[now][0]?size[ch[now][0]]:0);
if (v==key[now]){splay(now);return ans+1;}
ans+=cnt[now];now=ch[now][1];
}
}
}
inline int findx(int x)
{
int now=root;
while (1)
{
if (ch[now][0]&&x<=size[ch[now][0]])
now=ch[now][0];
else
{
int temp=(ch[now][0]?size[ch[now][0]]:0)+cnt[now];
if (x<=temp)return key[now];
x-=temp;now=ch[now][1];
}
}
}
inline int pre()
{
int now=ch[root][0];
while (ch[now][1])now=ch[now][1];
return now;
}
inline int suc()
{
int now=ch[root][1];
while(ch[now][0])now=ch[now][0];
return now;
}
inline void del(int x)
{
int whatever=find(x);
if (cnt[root]>1){cnt[root]--;updata(root);return;}
if (!ch[root][0]&&!ch[root][1]){clear(root);root=0;return;}
if (!ch[root][0])
{
int oldroot=root;root=ch[root][1];f[root]=0;clear(oldroot);return;
}
if (!ch[root][1])
{
int oldroot=root;root=ch[root][0];f[root]=0;clear(oldroot);return;
}
int leftbig=pre(),oldroot=root;
splay(leftbig);
f[ch[oldroot][1]]=root;
ch[root][1]=ch[oldroot][1];
clear(oldroot);
updata(root);
return;
}
inline int head(int x)
{
insert(x);int p=key[pre()];del(x);return p;
}
inline int next(int x)
{
insert(x);int p=key[suc()];del(x);return p;
}
}T;
int main()
{
// freopen("std.in","r",stdin);
int opt,opx;
n=F();T.sz=0;
while(n--)
{
// cout<<n<<endl;
opt=F(),opx=F();
if (opt==1)T.insert (opx);
else if (opt==2)T.del(opx);
else if (opt==3)printf("%d\n",T.find(opx));
else if (opt==4)printf("%d\n",T.findx(opx));
else if (opt==5)printf("%d\n",T.head(opx));
else if (opt==6)printf("%d\n",T.next(opx));
// for (int i=1;i<=T.sz;i++)
// cout<<T.key[i]<<' ';
// cout<<endl;
}
return 0;
}