初学,看的这篇博客
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<sstream>
/* TDD */
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define fi first
#define se second
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define sc(n) scanf("%d",&n)
#define SC(n,m) scanf("%d %d",&n,&m)
#define SZ(a) int((a).size())
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define drep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-9;
const int N=2e5+5;
int ch[N][2],val[N],cnt[N],par[N],sz[N],rev[N];
//x节点的左右儿子;x存储的权值;x存储的重复权值的个数;x的父亲节点;x子树下储存的权值数
//(包括重复);翻转标记
int root,ncnt;
int n,m;
il void pushup(int x){ sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x];}
il void pushdown(int x){
if(rev[x]){
swap(ch[x][0],ch[x][1]);
rev[ch[x][0]]^=1;
rev[ch[x][1]]^=1;
rev[x]=0;
}
}
il bool ws(int x){ return ch[par[x]][1]==x;}
void rotate(int x){
int f=par[x],ff=par[f],k=ws(x),w=ch[x][k^1];
ch[f][k]=w,par[w]=f;
ch[ff][ws(f)]=x,par[x]=ff;
ch[x][k^1]=f,par[f]=x;
pushup(f),pushup(x);
}
void splay(int x,int goal=0){
while(par[x]!=goal){
int f=par[x],ff=par[f];
if(ff!=goal){
if(ws(x)==ws(f)) rotate(f);
else rotate(x);
}
rotate(x);
}
if(!goal) root=x;
}
void Find(int x){ //找到x值并将其旋转为根
int cur=root;
while(ch[cur][x>val[cur]] && x!=val[cur]){
cur=ch[cur][x>val[cur]];
}
splay(cur);
}
void Insert(int x){
int cur=root,p=0;
while(cur && val[cur]!=x){
p=cur;
cur=ch[cur][x>val[cur]];
}
if(cur) cnt[cur]++;
else{
cur=++ncnt;
if(p) ch[p][x>val[p]]=cur;
ch[cur][0]=ch[cur][1]=0;
par[cur]=p,val[cur]=x;
cnt[cur]=sz[cur]=1;
}
splay(cur);
}
/*查询*/
int Kth(int k){ //第k-1大 (因为一开始插入了-inf)
int cur=root;
while(1){
pushdown(cur);//有区间操作时才需pushdown
if(ch[cur][0] && k<=sz[ch[cur][0]]) cur=ch[cur][0];
else if(k>sz[ch[cur][0]]+cnt[cur]){
k-=sz[ch[cur][0]]+cnt[cur];
cur=ch[cur][1];
}
else return cur;
}
}
void Rank(int x){ //x的rank
Find(x);
cout<<sz[ch[root][0]]<<endl;
}
int Pre(int x){ //x的前驱
Find(x);
if(val[root]<x) return root;
int cur=ch[root][0];
while(ch[cur][1]) cur=ch[cur][1];
return cur;
}
int Back(int x){ //x的后继
Find(x);
if(val[root]>x) return root;
int cur=ch[root][1];
while(ch[cur][0]) cur=ch[cur][0];
return cur;
}
void Remove(int x){ //删除x
int last=Pre(x),beh=Back(x);
splay(last),splay(beh,last);
int del=ch[beh][0];
if(cnt[del]>1){
cnt[del]--;
splay(del);
}
else ch[beh][0]=0;
}
void Reverse(int l,int r){ //翻转[l,r]区间
int x=Kth(l),y=Kth(r+2);
splay(x),splay(y,x);
rev[ch[y][0]]^=1;
}
void Output(int x){ //中序遍历输出
pushdown(x);
if(ch[x][0]) Output(ch[x][0]);
if(val[x]>=1 && val[x]<=n) printf("%d ",val[x]);
if(ch[x][1]) Output(ch[x][1]);
}
void Print(int l,int r){ //输出[l,r]
int x=Kth(l),y=Kth(r+2);
splay(x),splay(y,x);
Output(ch[y][0]);
}
int main(){
Insert(inf),Insert(-inf); //先形成树形
return 0;
}