【BZOJ 1552】[Cerc2007]robotic sort
2014-11-27 18:50
351 查看
1552: [Cerc2007]robotic sort
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 326 Solved: 133
[Submit][Status]
Description
Input
输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。Output
输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,(1 < = Pi < = N),Pi表示第i次操作前第i小的物品所在的位置。 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。Sample Input
63 4 5 1 6 2
Sample Output
4 6 4 5 6 6HINT
Source
HNOI2009集训Day6以位置为关键字的splay。
本题的大致思路就是每次找到整棵树中值最小的结点,把他旋到根结点即可求出他的位置,把他赋值为最大值(在根结点赋值只要Push_up(root)就可以了),然后反转区间,重复n次即可。
注意:
1.在数列中插入永远在排在最前和最后的两个值,赋值为最大值,方便后面操作
2.有权值相同的点输出在起始时候最早出现的位置,我解决的方法是:
每个结点多维护两个值:no,minno,分别表示在起始数列中的位置,和最小值出现的最早位置(在起始数列中最靠前)。
#include <iostream> #include <algorithm> #include <cstring> #include <cstdlib> #include <cstdio> #define maxn 0x7fffffff using namespace std; struct splay { int data,no,rev,l,r,fa,minn,size,minno; }a[100005]; int rr[100005],n,root,tot=0; void Push_up(int x) { a[x].size=1+a[a[x].r].size+a[a[x].l].size; a[x].minno=maxn; int minn=maxn; if (a[x].r) minn=a[a[x].r].minn,a[x].minno=a[a[x].r].minno; if (a[x].l&&a[a[x].l].minn<=minn) { if (minn==a[a[x].l].minn&&a[x].minno>a[a[x].l].minno) a[x].minno=a[a[x].l].minno; if (minn>a[a[x].l].minn) minn=a[a[x].l].minn,a[x].minno=a[a[x].l].minno; } a[x].minn=minn; if (a[x].data<=a[x].minn) { if (a[x].data==minn&&a[x].no<a[x].minno) a[x].minno=a[x].no; if (a[x].data<a[x].minn) a[x].minn=a[x].data,a[x].minno=a[x].no; } } void Push_down(int x) { if (a[x].rev) { a[x].rev=0; swap(a[x].l,a[x].r); a[a[x].l].rev^=1; a[a[x].r].rev^=1; } } void New_Node(int &x,int fa,int key,int no) { x=++tot; a[x].fa=fa; a[x].l=a[x].r=a[x].rev=a[x].size=0; a[x].data=key; a[x].no=no; } void Build(int &x,int fa,int l,int r) { if (l>r) return; int m=(l+r)>>1; New_Node(x,fa,rr[m],m-1); Build(a[x].l,x,l,m-1); Build(a[x].r,x,m+1,r); Push_up(x); } void zig(int x) { int y=a[x].fa; int z=a[y].fa; Push_down(y);Push_down(x); a[y].fa=x,a[x].fa=z; a[y].l=a[x].r,a[a[x].r].fa=y,a[x].r=y; if (y==a[z].l) a[z].l=x; else a[z].r=x; Push_up(y); } void zag(int x) { int y=a[x].fa; int z=a[y].fa; Push_down(y);Push_down(x); a[y].fa=x,a[x].fa=z; a[y].r=a[x].l,a[a[x].l].fa=y,a[x].l=y; if (y==a[z].l) a[z].l=x; else a[z].r=x; Push_up(y); } void splay(int x,int s) { Push_down(x); while (a[x].fa!=s) { int y=a[x].fa; int z=a[y].fa; if (z==s) { if (x==a[y].l) zig(x); else zag(x); break; } if (y==a[z].l) { if (x==a[y].l) zig(y),zig(x); else zag(x),zig(x); } else { if (x==a[y].r) zag(y),zag(x); else zig(x),zag(x); } } Push_up(x); if (s==0) root=x; } int Find(int x) { if ((a[x].data==a[x].minn)&&a[x].no==a[x].minno) return x; Push_down(x); if (a[a[x].l].minn==a[x].minn&&a[a[x].l].minno==a[x].minno) return Find(a[x].l); return Find(a[x].r); } int Findkth(int x,int k) { Push_down(x); int s=a[a[x].l].size; if (k==s+1) return x; if (s>=k) return Findkth(a[x].l,k); return Findkth(a[x].r,k-s-1); } int Getmin(int x) { Push_down(x); while (a[x].l) { x=a[x].l; Push_down(x); } return x; } int Findnext(int x) { return Getmin(a[root].r); } void Reserve(int x,int y) { splay(x,0); splay(y,root); a[a[y].l].rev^=1; } int main() { scanf("%d",&n); root=tot=0; for (int i=1;i<=n;i++) scanf("%d",&rr[i]); rr[0]=rr[n+1]=maxn; Build(root,0,0,n+1); for (int i=1;i<=n;i++) { int ans; ans=Find(root); splay(ans,0); a[root].data=maxn; Push_up(root); printf("%d",a[a[root].l].size); Reserve(Findkth(root,i),Findnext(ans)); if (i==n) printf("\n"); else printf(" "); } return 0; }
相关文章推荐
- BZOJ 1552/1506 [Cerc2007]robotic sort
- bzoj1552 [Cerc2007]robotic sort
- bzoj【1552/3506】[Cerc2007]robotic sort
- 【BZOJ】1552/3506 [Cerc2007]robotic sort
- BZOJ1552 [Cerc2007]robotic sort
- BZOJ 1552 [Cerc2007]robotic sort
- BZOJ 1552 [Cerc2007]robotic sort
- BZOJ 1552: [Cerc2007]robotic sort
- BZOJ1552: [Cerc2007]robotic sort
- BZOJ1552 [Cerc2007]robotic sort
- BZOJ1552: [Cerc2007]robotic sort
- bzoj3506【CQOI2014】排序机械臂 bzoj1552【CERC2007】robotic sort
- 【bzoj1552/3506】[Cerc2007]robotic sort
- BZOJ1552/3506 [Cerc2007]robotic sort
- bzoj 1552: [Cerc2007]robotic sort
- bzoj1552 [Cerc2007]robotic sort(splay)
- BZOJ 1552: [Cerc2007]robotic sort( splay )
- [BZOJ1552][Cerc2007]robotic sort(splay)
- BZOJ 1552: [Cerc2007]robotic sort/3506: [Cqoi2014]排序机械臂 splay
- 【bzoj1552】[Cerc2007]robotic sort splay