我们建棵平衡树,维护排名关系
TOP:将元素Splay到根,然后将左子树合并到该元素的后继
BOTTOM:将元素Splay到根,然后将右子树合并到该元素的前驱
(相当于强行更改偏序关系)
INSERT:直接与该元素的前驱/后继交换位置及信息
ASK:将元素Splay到根,输出左儿子的size
QUERY:第k大
一开始的插入由于是有序的,可以不用那么麻烦
#include<bits/stdc++.h>
const int N=80005;
using namespace std;
template<class T>
inline void read(T &x)
{
x=0; int f=1;
static char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') f=-1;
ch=getchar();
}
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
x*=f;
}
inline void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9) write(x/10);
putchar(x%10+'0');
}
struct Tree
{
int lc,rc,fa,size,val;
}t[N];
int n,m,id[N];
int root,tot;
inline int which(int u){return t[t[u].fa].rc==u;}