您的位置:首页 > 其它

[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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: