bzoj 1552: [Cerc2007]robotic sort(splay)

来源:互联网 发布:女神联盟英雄升阶数据 编辑:程序博客网 时间:2024/05/17 01:08

1552: [Cerc2007]robotic sort

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 740  Solved: 303
[Submit][Status][Discuss]

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

Sample Output

4 6 4 5 6 6

HINT

Source

HNOI2009集训Day6

[Submit][Status][Discuss]

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#define N 1000003#define inf 1000000000using namespace std;int n,a[N],key[N],b[N],p[N],root,sz;int fa[N],ch[N][3],size[N],rev[N],pos[N];int cmp(int x,int y){return a[x]<a[y]||a[x]==a[y]&&x<y;}int get(int x){return ch[fa[x]][1]==x;}void update(int x){size[x]=1;if (ch[x][0]) size[x]+=size[ch[x][0]];if (ch[x][1]) size[x]+=size[ch[x][1]];}void pushdown(int x){if (!rev[x])  return ;rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;swap(ch[x][0],ch[x][1]);rev[x]=0;}void rotate(int x){pushdown(fa[x]); pushdown(x);int y=fa[x]; int z=fa[y]; int which=get(x);if (z)  ch[z][ch[z][1]==y]=x;fa[x]=z; fa[y]=x; ch[y][which]=ch[x][which^1];fa[ch[y][which]]=y; ch[x][which^1]=y;update(y); update(x); }void splay(int x,int tar){for (int f;(f=fa[x])!=tar;rotate(x)) if (fa[f]!=tar)  rotate(get(x)==get(f)?f:x);if (!tar) root=x;}int find(int x){int now=root;while (true){pushdown(now);if (x<=size[ch[now][0]]) now=ch[now][0];else { int temp=size[ch[now][0]]+1; if (temp==x)  return now; x-=temp; now=ch[now][1]; }}}int build(int l,int r){if(l==r){sz++; pos[b[l]]=sz;  size[sz]=1;return sz;}if (l>r) return 0;int now=++sz; int mid=(l+r)/2; pos[b[mid]]=now;ch[now][0]=build(l,mid-1);ch[now][1]=build(mid+1,r);fa[ch[now][0]]=now; fa[ch[now][1]]=now; size[now]=size[ch[now][0]]+size[ch[now][1]]+1;return now;}int main(){freopen("a.in","r",stdin);freopen("my.out","w",stdout);scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d",&a[i]),p[i]=i;sort(p+1,p+n+1,cmp);int cnt=0;b[1]=0; b[n+2]=n+2;for (int i=1;i<=n;i++) b[p[i]+1]=i;root=build(1,n+2);for (int i=1;i<=n;i++) {    splay(pos[i],0); int ans=size[ch[root][0]]; if (i!=n) printf("%d ",ans); else printf("%d\n",ans); int aa=find(i);  int bb=find(ans+2); splay(aa,0); splay(bb,aa); rev[ch[ch[root][1]][0]]^=1; }}



0 0
原创粉丝点击