#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;
}