【splay】BZOJ 1152 && 3506:[cqoi2014]排序机械臂
来源:互联网 发布:网络机顶盒怎么设置 编辑:程序博客网 时间:2024/05/22 17:07
BZOJ 1152 && 3506:[cqoi2014]排序机械臂
Description
Input
输入共两行,第一行为一个整数N,N表示物品的个数,第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。
Output
输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,(1 < = Pi < = N),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
1<=N<=100000
Solution
普通的序列splay…
每个数对应在splay中的编号不变
维护区间最小值所在的编号
每次rev标记一下即可
初始要离散化
Code
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;#define maxn 100233struct splay{ int ch[2],fa,size,v; bool rev;}t[maxn*2];int pos[maxn],mn[maxn],ans[maxn];inline int in(){ int x=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar(); return x;}int root;struct sor{ int pos,v;}a[maxn];bool cmp(const sor A,const sor B){return (A.v<B.v||(A.v==B.v&&A.pos<B.pos));}bool cmp1(const sor A,const sor B){return A.pos<B.pos;}void pushdown(int k){ t[k].rev=0,t[t[k].ch[0]].rev^=1;t[t[k].ch[1]].rev^=1; swap(t[k].ch[0],t[k].ch[1]);}int find(int k,int x){ if(t[k].rev)pushdown(k); if(t[t[k].ch[0]].size>=x)return find(t[k].ch[0],x); else if(x>t[t[k].ch[0]].size+1)return find(t[k].ch[1],x-t[t[k].ch[0]].size-1); else return k;}void update(int k){ int l=t[k].ch[0],r=t[k].ch[1]; t[k].size=t[l].size+t[r].size+1; mn[k]=t[k].v,pos[k]=k; if(mn[l]<mn[k]){mn[k]=mn[l];pos[k]=pos[l];} if(mn[r]<mn[k]){mn[k]=mn[r];pos[k]=pos[r];}}void rotate(int x,int &k,int d){ int y,z; y=t[x].fa;z=t[y].fa; if(y==k)k=x; else {if(t[z].ch[0]==y)t[z].ch[0]=x;else t[z].ch[1]=x;} t[y].fa=x,t[x].fa=z,t[t[x].ch[d]].fa=y; t[y].ch[d^1]=t[x].ch[d];t[x].ch[d]=y; update(y),update(x);}int s[maxn],top=0;void splay(int x,int &k){ top=0;s[++top]=x; for(int i=x;t[i].fa;i=t[i].fa) s[++top]=t[i].fa; for(;top;top--) if(t[s[top]].rev)pushdown(s[top]); int y,z; while(x!=k) { y=t[x].fa;z=t[y].fa; if(y!=k) { if(t[z].ch[0]==y&&t[y].ch[0]==x)rotate(y,k,1); else if(t[z].ch[1]==y&&t[y].ch[1]==x)rotate(y,k,0); else if(t[z].ch[0]==y&&t[y].ch[1]==x)rotate(x,k,0); else if(t[z].ch[1]==y&&t[y].ch[0]==x)rotate(x,k,1); } if(t[t[x].fa].ch[0]==x)rotate(x,k,1); else rotate(x,k,0); }}void build(int l,int r,int f){ if(r<l)return; if(l==r) { mn[l]=a[l].v; t[l].size=1;t[l].fa=f; t[l].v=a[l].v; pos[l]=l; t[f].ch[r>f]=r; return; } int mid=(l+r)>>1; build(l,mid-1,mid);build(mid+1,r,mid); t[mid].v=a[mid].v; update(mid);t[mid].fa=f; t[f].ch[mid>f]=mid;}int querymn(int L,int R){ int ans1=find(root,L),ans2=find(root,R+2); splay(ans1,root),splay(ans2,t[root].ch[1]); return pos[t[ans2].ch[0]];}void rever(int L,int R){ int ans1=find(root,L),ans2=find(root,R+2); splay(ans1,root),splay(ans2,t[root].ch[1]); t[t[ans2].ch[0]].rev^=1;}int main(){ freopen("1552.in","r",stdin); int n; n=in(); a[1].v=a[n+2].v=99999999,mn[0]=99999999; for(int i=2;i<=n+1;i++) { a[i].v=in(); a[i].pos=i-1; } sort(a+2,2+a+n,cmp); for(int i=2;i<=n+1;i++)a[i].v=i-1; sort(a+2,a+2+n,cmp1); build(1,n+2,0); root=(n+3)>>1; for(int i=1;i<=n;i++) { int x=querymn(i,n); splay(x,root); ans[i]=t[t[x].ch[0]].size; rever(i,ans[i]); } for(int i=1;i<=n;i++)printf("%d ",ans[i]); return 0;}
1 0
- 【splay】BZOJ 1152 && 3506:[cqoi2014]排序机械臂
- bzoj 1552: [Cerc2007]robotic sort && bzoj 3506: [Cqoi2014]排序机械臂(splay区间翻转)
- BZOJ 1552: [Cerc2007]robotic sort/3506: [Cqoi2014]排序机械臂 splay
- CQOI2014 排序机械臂--splay膜版题
- 【jzoj3599】【CQOI2014】【排序机械臂】【splay】
- 【BZOJ】【P1552&3506】【Cqoi2014】【排序机械臂】【题解】【Treap】
- 【CQOI2014】【BZOJ 3506】【JZOJ 3599】排序机械臂
- BZOJ3506 [Cqoi2014]排序机械臂(离散化+Splay)
- 【CQOI2014】排序机械臂
- 【CQOI2014】排序机械臂
- 【CQOI2014】排序机械臂
- BZOJ 3506 CQOI 2014 排序机械臂 Splay
- bzoj3506 [Cqoi2014]排序机械臂
- [BZOJ3506]CQOI2014排序机械臂
- 【bzoj3506】【CQOI2014】排序机械臂
- JZOJ3599【CQOI2014】排序机械臂
- bzoj3506&1552 [Cerc2007][Cqoi2014]robotic sort 排序机械臂(splay)
- 排序机械臂 <Splay>
- 【Android实战】图片选取、拍摄、裁剪、上传
- 大数据学习
- 简单dp(codeforce #336(c)补题
- 关于<您需要来自S-1-5-21-XXXXXXXXXXX 的权限>的错误解决方法
- 18-6
- 【splay】BZOJ 1152 && 3506:[cqoi2014]排序机械臂
- Intel大战高通、三星:结果瞠目结舌!
- Servlet基础
- 记一次驴唇不对马嘴的DIY之旅(五)
- ubuntun下的Nvidia显卡安装
- C++-类的理解
- 网站设计2
- 圣杯布局和双飞翼布局
- 吾之简单的KMP算法学习,字符串操作基本功