BZOJ4825 [Hnoi2017]单旋

HNOID1每道题都已小于2s的差距领先ljss交到BZ上23333

论快捷键提交的优越性

考虑一次插入了x,x的前驱为pre,后继为nxt,平衡树中排名相邻的两个点一定互为祖先关系,那么如果pre为nxt的祖先,x就插入到了nxt的左儿子,如果nxt为pre的祖先,x就插入到了pre的右儿子

考虑把最小值旋到根的操作,最小值没有左子树,最小值的右子树变成了最小值父亲的左子树,根变成了最小值的右儿子

把最大值旋到根同理

那么用ETT来维护这个spaly即可

ljss告诉我们不用ETT直接写splay来维护dfs序也行

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAXN 400010
#define MAXM 1010
#define ll long long
#define eps 1e-8
#define MOD 1000000007
#define INF 1000000000
#define tr son[son[rt][1]][0]
char xB[1<<15],*xS=xB,*xTT=xB;
#define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)
#define isd(c) (c>='0'&&c<='9')
int read(){
	char xchh;
	int xaa;
    while(xchh=getc(),!isd(xchh));(xaa=xchh-'0');
    while(xchh=getc(),isd(xchh))xaa=xaa*10+xchh-'0';return xaa;
}

int m;
mapL,R;
setS;
int tot;
int fa[MAXN],son[MAXN][2],v[MAXN],sum[MAXN];
int rt;
void tpt(){
	int i;
	cerr<::iterator it,itp,itn;
	m=read();
	while(m--){
		o=read();
		if(o==1){
			x=read();
			v[L[x]=++tot]=1;
			v[R[x]=++tot]=-1;
			it=(S.insert(x)).first;
			if(S.size()==1){
				rt=tot-1;
				fa[tot]=tot-1;
				son[tot-1][1]=tot;
				ud(tot);
				ud(tot-1);
			}else if(it==S.begin()){
				ins1(L[*(++it)]);
			}else if(it==(--S.end())){
				ins2(R[*(--it)]);
			}else{
				itn=itp=it;
				int pre=L[*(--itp)],nxt=L[*(++itn)];
				if(ask(pre)


你可能感兴趣的:(BZOJ,ETT)