对应模板题
照着巨佬博客的代码打的https://blog.csdn.net/Clove_unique/article/details/50630280
#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iomanip>
#include<sstream>
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define next _next
#define insert _insert
#define size _size
//#define ll __int64
//#define int ll
typedef long long ll;
typedef unsigned long long ull;
const int MAXN=1e6+10;
const int MOD=1e9+7;
const double eps=1e-6;
const double finf=1e10;
using namespace std;
template<class T>inline void read(T &res)
{
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
//-------------------------------------------//
int fa[MAXN],ch[MAXN][2],size[MAXN],key[MAXN],cnt[MAXN],root,sz;
inline void clear(int x)
{
ch[x][0]=ch[x][1]=fa[x]=size[x]=key[x]=cnt[x]=0;
}
inline int check(int x)
{
return ch[fa[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=fa[x],oldf=fa[fa[x]],which=check(x);
ch[old][which]=ch[x][which^1];fa[ch[x][which^1]]=old;
ch[x][which^1]=old;fa[old]=x;
fa[x]=oldf;
if(oldf)ch[oldf][ch[oldf][1]==old]=x;
updata(old);updata(x);
}
inline void splay(int x)
{
for(int f;f=fa[x];rotate(x))
if(fa[f])rotate((check(x)==check(f))?f:x);
root=x;
}
inline void insert(int x)
{
if(!root)
{
sz++;ch[sz][0]=ch[sz][1]=fa[sz]=0;key[sz]=x;
cnt[sz]=size[sz]=1;root=sz;return;
}
int cur=root,father=0;
while(1)
{
if(key[cur]==x)
{
cnt[cur]++;updata(cur);updata(father);
splay(cur);break;
}
father=cur;
cur=ch[cur][key[cur]<x];
if(!cur)
{
sz++;
ch[sz][0]=ch[sz][1]=0;
fa[sz]=father;
size[sz]=cnt[sz]=1;
ch[father][key[father]<x]=sz;
key[sz]=x;
updata(father);
splay(sz);break;
}
}
}
inline int find_val(int x)
{
int res=0,cur=root;
while(1)
{
if(x<key[cur])cur=ch[cur][0];
else
{
res+=(ch[cur][0]?size[ch[cur][0]]:0);
if(x==key[cur]){splay(cur);return res+1;}
res+=cnt[cur];
cur=ch[cur][1];
}
}
}
inline int find_k(int k)
{
int cur=root;
while(1)
{
if(ch[cur][0]&&k<=size[ch[cur][0]])cur=ch[cur][0];
else
{
int temp=(ch[cur][0]?size[ch[cur][0]]:0)+cnt[cur];
if(k<=temp)return key[cur];
k-=temp; cur=ch[cur][1];
}
}
}
inline int pre()
{
int cur=ch[root][0];
while (ch[cur][1]) cur=ch[cur][1];
return cur;
}
inline int next()
{
int cur=ch[root][1];
while (ch[cur][0]) cur=ch[cur][0];
return cur;
}
inline void del(int x)
{
find_val(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 oldrt=root; root=ch[root][1]; fa[root]=0; clear(oldrt); return;}
else if(!ch[root][1]){int oldrt=root; root=ch[root][0]; fa[root]=0; clear(oldrt); return;}
int newrt=pre(),oldrt=root;
splay(newrt);
fa[ch[oldrt][1]]=root;
ch[root][1]=ch[oldrt][1];
clear(oldrt);
updata(root);
}
int main()
{
int n,op,x;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&op,&x);
switch(op)
{
case 1:insert(x); break;
case 2:del(x); break;
case 3:printf("%d\n",find_val(x)); break;
case 4:printf("%d\n",find_k(x)); break;
case 5:insert(x); printf("%d\n",key[pre()]);del(x);break;
case 6:insert(x); printf("%d\n",key[next()]);del(x);break;
}
}
return 0;
}
splay’s应用:区间翻转
文艺平衡树
#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iomanip>
#include<sstream>
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define next _next
#define insert _insert
#define size _size
//#define ll __int64
//#define int ll
typedef long long ll;
typedef unsigned long long ull;
const int MAXN=1e6+10;
const int MOD=1e9+7;
const double eps=1e-6;
const double finf=1e10;
using namespace std;
template<class T>inline void read(T &res)
{
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
//-------------------------------------------//
int fa[MAXN],ch[MAXN][2],size[MAXN],key[MAXN],lazy[MAXN],a[MAXN],root,sz;
inline void clear(int x)
{
ch[x][0]=ch[x][1]=fa[x]=size[x]=key[x]=0;
}
inline int check(int x)
{
return ch[fa[x]][1]==x;
}
inline void pushdown(int x)
{
if(x&&lazy[x])
{
lazy[ch[x][0]]^=1;
lazy[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
lazy[x]=0;
}
}
inline void updata(int x)
{
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
inline void rotate(int x)
{
pushdown(fa[x]);pushdown(x);
int old=fa[x],oldf=fa[fa[x]],which=check(x);
ch[old][which]=ch[x][which^1]; fa[ch[x][which^1]]=old;
ch[x][which^1]=old; fa[old]=x;
fa[x]=oldf;
if(oldf)ch[oldf][ch[oldf][1]==old]=x;
updata(old);updata(x);
}
inline void splay(int x,int tar)
{
for(int f;(f=fa[x])!=tar;rotate(x))
if(fa[f]!=tar)rotate((check(x)==check(f))?f:x);
if(tar==0)root=x;
}
inline int build(int l,int r,int pre)
{
if(l>r)return 0;
int m=l+r>>1;
int cur=++sz;
key[cur]=a[m]; fa[cur]=pre; lazy[cur]=0;
ch[cur][0]=build(l,m-1,cur);
ch[cur][1]=build(m+1,r,cur);
updata(cur);
return cur;
}
inline int find_k(int k)
{
int cur=root;
while(1)
{
pushdown(cur);
if(ch[cur][0]&&k<=size[ch[cur][0]])cur=ch[cur][0];
else
{
k-=size[ch[cur][0]]+1;
if(!k)return cur;
cur=ch[cur][1];
}
}
}
inline void print(int cur)
{
pushdown(cur);
if(ch[cur][0])print(ch[cur][0]);
if(key[cur]!=-INF&&key[cur]!=INF)printf("%d ",key[cur]);
if(ch[cur][1])print(ch[cur][1]);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)a[i]=i;
a[0]=-INF;a[n+1]=INF;
root=build(0,n+1,0);
while(m--)
{
int l,r;
scanf("%d%d",&l,&r);
int x=find_k(l);
int y=find_k(r+2);
splay(x,0);
splay(y,x);
lazy[ch[ch[root][1]][0]]^=1;
}
print(root);
return 0;
}