BZOJ 1552: [Cerc2007]robotic sort/3506: [Cqoi2014]排序机械臂 splay
2017-10-19 15:04
483 查看
1552: [Cerc2007]robotic sort
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1273 Solved: 488
[Submit][Status][Discuss]
Description
![](https://oscdn.geek-share.com/Uploads/Images/Content/201708/761d2c66f7e50ee419eb8e0e7157ded2.jpg)
Input
输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。
Output
输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,Pi表示第i次操作前第i小的物品所在的位置。注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。
Sample Input
63 4 5 1 6 2
Sample Output
4 6 4 5 6 6发现自己又不会写splay了 GG
这题很水啊。。。我竟然硬是搞了两个小时。。。
只需要维护子树内权值最小的点的标号就好了
最开始打挂 然后狂调 最后越调越乱
无奈的重构代码
最后 这成为了我有史以来写的最好的一棵splay
#include<cmath> #include<ctime> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #include<iomanip> #include<vector> #include<string> #include<bitset> #include<queue> #include<set> #include<map> using namespace std; typedef long long ll; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } void print(int x) {if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');} const int N=100100,inf=0X3f3f3f3f; struct node{int val,pos;friend bool operator <(const node &x,const node &y){return x.val==y.val?x.pos<y.pos:x.val<y.val;}}p ; inline bool cmp(const node &x,const node &y){return x.pos<y.pos;} int n; int root,ch [2],fa ,V ,mn ,size ; bool rev ; int pos ; inline void pushup(int k) { size[k]=size[ch[k][0]]+size[ch[k][1]]+1; mn[k]=k; if(ch[k][0]&&V[mn[ch[k][0]]]<V[mn[k]])mn[k]=mn[ch[k][0]]; if(ch[k][1]&&V[mn[ch[k][1]]]<V[mn[k]])mn[k]=mn[ch[k][1]]; } inline void pushdown(int k) { if(rev[k]) { rev[k]=0; swap(ch[k][0],ch[k][1]); rev[ch[k][0]]^=1;rev[ch[k][1]]^=1; } } inline void getdown(int k) {if(fa[k])getdown(fa[k]);pushdown(k);} int build(int l,int r,int pre) { if(l>r)return 0; int mid=(l+r)>>1; fa[mid]=pre; V[mid]=p[mid].val; ch[mid][0]=build(l,mid-1,mid); ch[mid][1]=build(mid+1,r,mid); pushup(mid); return mid; } inline int find(int rk) { int k=root; while(rk) { pushdown(k); if(size[ch[k][0]]>=rk)k=ch[k][0]; else if(size[ch[k][0]]+1<rk)rk-=size[ch[k][0]]+1,k=ch[k][1]; else return k; } } inline void rotate(int x,int &k) { int y=fa[x],z=fa[y],l,r; l=(ch[y][1]==x);r=l^1; y==k?k=x:ch[z][ch[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; ch[y][l]=ch[x][r];ch[x][r]=y; pushup(y);pushup(x); } void splay(int x,int &k) { getdown(x); int y,z; while(x!=k) { y=fa[x],z=fa[y]; if(y!=k) { if((ch[y][0]==x)^(ch[z][0]==y))rotate(x,k); else rotate(y,k); } rotate(x,k); } } int query_mn(int x,int y) { x=find(x);y=find(y+2); splay(x,root);splay(y,ch[x][1]); return mn[ch[y][0]]; } void rever(int x,int y) { x=find(x),y=find(y+2); splay(x,root);splay(y,ch[x][1]); rev[ch[y][0]]^=1; } int main() { n=read(); register int i,x; p[1].val=p[n+2].val=inf; for(i=2;i<=n+1;++i)p[i].val=read(),p[i].pos=i; sort(p+2,p+2+n); for(i=2;i<=n+1;++i)p[i].val=i; sort(p+2,p+2+n,cmp); root=build(1,n+2,0); for(i=1;i<=n;++i) { x=query_mn(i,n); splay(x,root); print(size[ch[x][0]]); if(i^n)putchar(' '); rever(i,size[ch[x][0]]); } puts("");return 0; } /* 6 3 4 5 1 6 2 4 6 4 5 6 6 */
相关文章推荐
- 【BZOJ】【1552】【Cerc2007】robotic sort / 【3506】【CQOI2014】排序机械臂
- bzoj3506&1552 [Cerc2007][Cqoi2014]robotic sort 排序机械臂(splay)
- bzoj 1552: [Cerc2007]robotic sort && bzoj 3506: [Cqoi2014]排序机械臂(splay区间翻转)
- bzoj3506【CQOI2014】排序机械臂 bzoj1552【CERC2007】robotic sort
- 【splay】BZOJ 1152 && 3506:[cqoi2014]排序机械臂
- BZOJ 3506 CQOI 2014 排序机械臂 Splay
- 【BZOJ-1552&3506】robotic sort&排序机械臂 Splay
- BZOJ_1552_[Cerc2007]robotic sort_splay
- 【BZOJ】【P1552&3506】【Cqoi2014】【排序机械臂】【题解】【Treap】
- 【CQOI2014】【BZOJ 3506】【JZOJ 3599】排序机械臂
- bzoj1552 [Cerc2007]robotic sort(splay)
- bzoj3506 [Cqoi2014]排序机械臂(同bzoj1552)
- bzoj 1552: [Cerc2007]robotic sort(splay)
- bzoj3506 [Cqoi2014]排序机械臂
- 【bzoj3506】【CQOI2014】排序机械臂
- BZOJ3506 [Cqoi2014]排序机械臂(离散化+Splay)
- Bzoj3506: [Cqoi2014]排序机械臂
- Bzoj3506: [Cqoi2014]排序机械臂
- 【BZOJ1552】[Cerc2007]robotic sort Splay
- [BZOJ1552][Cerc2007]robotic sort(splay)