# BZOJ3506: [Cqoi2014]排序机械臂

BZOJ3506: [Cqoi2014]排序机械臂

## 输入输出样例

6
3 4 5 1 6 2

4 6 4 5 6 6

N<=100000

Pi<=10^7

## 题解Here!

1. 头尾设两个哨兵节点。
2. $splay$每次都要$pushdown$一次（巨坑）！

#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 100010
#define MAX 999999999
using namespace std;
int n,size=1,root=0;
struct node{
int x,id;
}b[MAXN];
namespace splay{
struct Splay{
int f,s,flag,son[2];
int v;
}a[MAXN];
inline void clean(int rt){
a[rt].son[0]=a[rt].son[1]=a[rt].f=a[rt].s=a[rt].flag=a[rt].v=0;
}
inline void pushup(int rt){
if(!rt)return;
a[rt].s=a[a[rt].son[0]].s+a[a[rt].son[1]].s+1;
}
inline void pushdown(int rt){
if(!rt||!a[rt].flag)return;
a[a[rt].son[0]].flag^=1;a[a[rt].son[1]].flag^=1;a[rt].flag^=1;
swap(a[rt].son[0],a[rt].son[1]);
}
inline void turn(int rt,int k){
int x=a[rt].f,y=a[x].f;
a[x].son[k^1]=a[rt].son[k];
if(a[rt].son[k])a[a[rt].son[k]].f=x;
a[rt].f=y;
if(y)a[y].son[a[y].son[1]==x]=rt;
a[x].f=rt;
a[rt].son[k]=x;
pushup(x);pushup(rt);
}
void splay(int rt,int ancestry){
while(a[rt].f!=ancestry){
int x=a[rt].f,y=a[x].f;
pushdown(y);pushdown(x);pushdown(rt);
if(y==ancestry)turn(rt,a[x].son[0]==rt);
else{
int k=a[y].son[0]==x?1:0;
if(a[x].son[k]==rt){turn(rt,k^1);turn(rt,k);}
else{turn(x,k);turn(rt,k);}
}
}
if(ancestry==0)root=rt;
}
inline int newnode(int x){
int rt=size++;
clean(rt);
a[rt].v=x;a[rt].s=1;
return rt;
}
int buildtree(int l,int r){
if(l>r)return 0;
int mid=l+r>>1,lson=0,rson=0;
lson=buildtree(l,mid-1);
int rt=newnode(b[mid].x);
rson=buildtree(mid+1,r);
a[rt].son[0]=lson;
a[rt].son[1]=rson;
if(lson)a[lson].f=rt;
if(rson)a[rson].f=rt;
pushup(rt);
return rt;
}
int kth(int rt,int k){
if(a[rt].s<k)return 0;
while(1){
pushdown(rt);
int y=a[rt].son[0];
if(k>a[y].s+1){
k-=a[y].s+1;
rt=a[rt].son[1];
}
else if(k<=a[y].s)rt=y;
else return rt;
}
}
inline void reverse(int i){
splay(b[i].id+1,0);
int s=a[a[root].son[0]].s;
printf("%d ",s);
int front=kth(root,i),next=kth(root,s+2);
splay(front,0);splay(next,front);
a[a[next].son[0]].flag^=1;
}
}
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
bool cmp(const node &x,const node &y){
if(x.x==y.x)return x.id<y.id;
return x.x<y.x;
}
void init(){
for(int i=1;i<=n;i++){
b[i].id=i;
}
b[0].x=-MAX;b[0].id=1;
b[n+1].x=MAX;b[n+1].id=n+1;
sort(b+1,b+n+1,cmp);
root=splay::buildtree(0,n+1);
for(int i=1;i<=n-1;i++)splay::reverse(i);
printf("%d\n",n);
}
int main(){
init();
return 0;
}


posted @ 2018-11-10 19:50 符拉迪沃斯托克 阅读(...) 评论(...) 编辑 收藏
Live2D