[CQOI2014]排序机械臂
2018-01-11 15:58
204 查看
Description
Solution
一道很水很水的题,splay树保存一个最小值,每次查找最小值所在的位置,旋转到根,输出它在第几位。然后将它之前的节点打上翻转标记,维护一下即可。注意这道题要先排序,因为翻转操作之后就不知到它原来的位置了。
//Never forget why you start #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #define ll(x) bst[x].child[0] #define rr(x) bst[x].child[1] #define son(x,t) bst[x].child[t] #define inf (2147483647) using namespace std; int root,n,cnt; struct point{ int x,id; }a[100005]; bool cmp1(const point a,const point b){ return a.x<b.x||(a.x==b.x&&a.id<b.id); } bool cmp2(const point a,const point b){ return a.id<b.id; } struct BST{ int child[2],fa,mmin,x,size,lazy; }bst[100005]; void push_up(int root){ int l=ll(root),r=rr(root); bst[root].mmin=bst[root].x; if(l)bst[root].mmin=min(bst[root].mmin,bst[l].mmin); if(r)bst[root].mmin=min(bst[root].mmin,bst[r].mmin); bst[root].size=bst[l].size+bst[r].size+1; } void push_down(int root){ int l=ll(root),r=rr(root); if(bst[root].lazy){ if(l)bst[l].lazy^=1; if(r)bst[r].lazy^=1; bst[root].lazy^=1; swap(ll(root),rr(root)); } } void rotate(int r,int t){ int fa=bst[r].fa; son(fa,!t)=son(r,t);bst[son(r,t)].fa=fa; son(bst[fa].fa,son(bst[fa].fa,1)==fa)=r;bst[r].fa=bst[fa].fa; son(r,t)=fa;bst[fa].fa=r; push_up(fa); push_up(r); } void splay(int r,int goal){ int fa=bst[r].fa; while(fa!=goal){ if(bst[fa].fa==goal)rotate(r,son(fa,0)==r); else{ int t=son(bst[fa].fa,0)==fa; if(son(fa,t)==r)rotate(r,!t),rotate(r,t); else rotate(fa,t),rotate(r,t); } fa=bst[r].fa; } if(goal==0)root=r; } int search(int root){ push_down(root); if(bst[root].mmin==bst[ll(root)].mmin)return search(ll(root)); if(bst[root].mmin==bst[root].x)return root; if(bst[root].mmin==bst[rr(root)].mmin)return search(rr(root)); } int find(int root,int k){ push_down(root); int y=bst[ll(root)].size; if(y+1==k)return root; else if(y>=k)return find(ll(root),k); else return find(rr(root),k-y-1); } void build(int &root,int left,int right,int fa){ int mid=(left+right)>>1; root=++cnt; bst[root].fa=fa; if(left==right){ bst[root].x=bst[root].mmin=a[left].x; bst[root].size=1; return; } if(left<mid)build(ll(root),left,mid-1,root); if(mid<right)build(rr(root),mid+1,right,root); bst[root].x=a[mid].x;bst[root].size=1; push_up(root); } int split(int l,int r){ l--;r++; int x=find(root,l),y=find(root,r); splay(x,0); splay(y,x); return ll(y); } void delet(int pos){ splay(pos,0); int x=find(root,bst[ll(pos)].size); int y=find(root,bst[ll(pos)].size+2); splay(x,0); splay(y,x); son(y,0)=0; bst[pos].fa=0; push_up(y); push_up(x); } int main(){ int i,j; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i+1].x),a[i+1].id=i; sort(a+2,a+n+2,cmp1); for(i=1;i<=n;i++) a[i+1].x=i; sort(a+2,a+n+2,cmp2); n+=2; a[1].x=a .x=inf; bst[0].x=bst[0].mmin=inf; bst[0].size=0; build(root,1,n,0); for(i=0;i<=n-3;i++){ int x=split(2,n-1-i); x=search(x); splay(find(root,1),0); splay(x,root); bst[ll(x)].lazy^=1; printf("%d ",bst[ll(x)].size+1+i); delet(x); } return 0; }
相关文章推荐
- [bzoj1552\bzoj2506][Cqoi2014]robotic sort 排序机械臂_非旋转Treap
- bzoj3506【CQOI2014】排序机械臂 bzoj1552【CERC2007】robotic sort
- [CQOI 2014] 排序机械臂
- 【平衡树维护序列】BZOJ3506(Cqoi2014)[排序机械臂]题解
- 【splay】BZOJ 1152 && 3506:[cqoi2014]排序机械臂
- bzoj3506 [Cqoi2014]排序机械臂
- 【CQOI2014】【BZOJ 3506】【JZOJ 3599】排序机械臂
- 【BZOJ】【1552】【Cerc2007】robotic sort / 【3506】【CQOI2014】排序机械臂
- 【CQOI2014】排序机械臂
- BZOJ 3506 CQOI 2014 排序机械臂 Splay
- [CQOI2014]排序机械臂
- 【CQOI2014】排序机械臂
- BZOJ 1552: [Cerc2007]robotic sort/3506: [Cqoi2014]排序机械臂 splay
- [CQOI2014]排序机械臂
- [BZOJ3506]CQOI2014排序机械臂
- Bzoj3506: [Cqoi2014]排序机械臂
- 【jzoj3599】【CQOI2014】【排序机械臂】【splay】
- 【BZOJ】【P1552&3506】【Cqoi2014】【排序机械臂】【题解】【Treap】
- JZOJ3599【CQOI2014】排序机械臂
- Bzoj3506: [Cqoi2014]排序机械臂