Description
Input
输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。
第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。
Output
输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,Pi表示第i次操作前第i小的物品所在的位置。
注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。
Sample Input
6
3 4 5 1 6 2
3 4 5 1 6 2
Sample Output
4 6 4 5 6 6
记录下每个装置对应位置然后依次splay翻转区间即可。
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #define N (100000+100) using namespace std; struct node { int id,num; } b[N]; int Key[N],Rev[N],Size[N]; int Father[N],Son[N][2]; int n,Root,a[N],Rank[N]; bool cmp(node a,node b) { return a.num==b.num?a.id<b.id:a.num<b.num; } inline int Get(int x) { return Son[Father[x]][1]==x; } inline void Update(int x) { Size[x]=Size[Son[x][0]]+Size[Son[x][1]]+1; } inline void Pushdown(int x) { if (Rev[x]) { Rev[x]=0; swap(Son[x][0],Son[x][1]); Rev[Son[x][0]]^=1; Rev[Son[x][1]]^=1; } } inline void Rotate(int x) { Pushdown(Father[x]); Pushdown(x); int wh=Get(x); int fa=Father[x],fafa=Father[fa]; Son[fa][wh]=Son[x][wh^1]; Father[fa]=x; if (Son[fa][wh]) Father[Son[fa][wh]]=fa; Son[x][wh^1]=fa; Father[x]=fafa; if (fafa) Son[fafa][Son[fafa][1]==fa]=x; Update(fa); Update(x); } inline void Splay(int x,int tar) { for (int fa;(fa=Father[x])!=tar;Rotate(x)) if (Father[fa]!=tar) Rotate(Get(fa)==Get(x)?fa:x); if (!tar) Root=x; } void Build(int l,int r,int fa) { if (l>r) return; if (l==r) { Size[l]=1; Father[l]=fa; Son[fa][l>fa]=l; return; } int mid=(l+r)>>1; Build(l,mid-1,mid); Build(mid+1,r,mid); Father[mid]=fa; Son[fa][mid>fa]=mid; Update(mid); } int Findx(int x) { int now=Root; while (1) { Pushdown(now); if (Size[Son[now][0]]>=x) now=Son[now][0]; else { x-=Size[Son[now][0]]; if (x==1) { Splay(now,0); return now; } x--; now=Son[now][1]; } } } inline int Split(int x,int y) { int xx=Findx(x),yy=Findx(y); Splay(xx,0); Splay(yy,xx); return Son[yy][0]; } int main() { scanf("%d",&n); for (int i=1; i<=n; ++i) { scanf("%d",&a[i+1]); b[i].id=i+1; b[i].num=a[i+1]; } sort(b+1,b+n+1,cmp); for (int i=1; i<=n; ++i) Rank[i]=b[i].id; Build(1,n+2,0); Root=(n+3)/2; for (int i=1; i<=n; ++i) { Splay(Rank[i],0); int ans=Size[Son[Root][0]]+1; printf("%d ",ans-1); int hh=Split(i,ans+1); Rev[hh]^=1; } }