#Splay#U137476 序列

题目

给定长度为(n)的序列(Ai) ,我们将按照如下操作给(Ai) 排序,

先找到编号最小的所在位置(x1) ,将([1,x1]) 翻转,

再找到编号第二小的所在位置(x2) ,将([1,x2]) 翻转,

如果有相同的(Ai) ,则按照输入顺序操作。输出所有的(xi)

Sample Input:
6
3 4 5 1 6 2

Sample Output:
4 6 4 5 6 6


分析

Splay裸题,但赛时不会Splay,wtcl

这道题的关键就是记录每个数的在Splay中的编号,

要注意相同的数按照输入顺序操作,所以不能够直接建树,要一个个插入

那么将操作的编号按照数的大小排序,相同编号小则优先,那么得到编号就很容易寻找排名了


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int inf=0x7fffffff,N=100011; int b[N],ans[N],n;
inline signed iut(){
	rr int ans=0,f=1; rr char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans*f;
}
inline void print(int ans){
	if (ans<0) putchar('-'),ans=-ans;
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
struct Splay{
	int siz[N],lazy[N],cnt[N],son[N][2],fat[N],w[N],root,tot;
	inline void pup(int x){siz[x]=siz[son[x][0]]+siz[son[x][1]]+cnt[x];}
	inline bool Is_R(int x){return son[fat[x]][1]==x;}
	inline void pdown(int x){
		if (x&&lazy[x]){
			lazy[son[x][0]]^=1,lazy[son[x][1]]^=1;
			swap(son[x][0],son[x][1]),lazy[x]=0;
		}
	} 
    inline void rotate(int x){
    	rr int Fa=fat[x],FFa=fat[Fa],wh=Is_R(x);
    	son[FFa][Is_R(Fa)]=x,fat[x]=FFa,son[Fa][wh]=son[x][wh^1];
    	fat[son[x][wh^1]]=Fa,son[x][wh^1]=Fa,fat[Fa]=x,pup(Fa),pup(x);
	}
	inline void update(int x,int tar){
		if (x==tar) return;
		update(fat[x],tar),pdown(x);
	}
	inline void splay(int x,int tar){
		update(x,tar);
		for (;fat[x]!=tar;rotate(x)){
			rr int Fa=fat[x],FFa=fat[Fa];
			if (FFa!=tar) rotate((Is_R(x)^Is_R(Fa))?x:Fa);
		}
		if (!tar) root=x;
	}
    inline signed rank(int x){
        splay(x,0);
        return siz[son[root][0]];
    }
	inline signed kth_site(int rk){
		rr int now=root;
		if (siz[now]<rk) return -1;
		while (1){
			pdown(now);
			rr int lson=son[now][0];
			if (siz[lson]+cnt[now]<rk)
				rk-=siz[lson]+cnt[now],now=son[now][1];
				else if (rk<=siz[lson]) now=son[now][0];
				    else break;
		}
		splay(now,0);
		return now;
	}
	inline void Invert(int L,int R){
		rr int l=kth_site(L-1),r=kth_site(R+1);
		splay(l,0),splay(r,l);
		lazy[son[son[root][1]][0]]^=1;
	}
}Tre;
bool cmp(int x,int y){return (Tre.w[x]^Tre.w[y])?Tre.w[x]<Tre.w[y]:x<y;}
signed main(){
    n=iut(),Tre.w[1]=-inf,Tre.w[n+2]=inf;
    for (rr int i=2;i<n+2;++i) Tre.w[i]=iut();
	for (rr int i=1;i<=n+2;++i)
	    Tre.son[i-1][1]=i,Tre.fat[i]=i-1,Tre.lazy[i]=0,
		    b[i]=i,Tre.cnt[i]=1,Tre.pup(i);
    Tre.root=n+2,sort(b+1,b+2+n,cmp);
	for (rr int i=2;i<n+2;++i){
		rr int l=i,r=Tre.rank(b[i])+1;
		Tre.Invert(l,r),ans[i-1]=r-1;
	}
	for (rr int i=1;i<=n;++i) print(ans[i]),putchar(i==n?10:32);
	return 0;
}
原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13880380.html