BZOJ1552/3506 robotic sort (Splay 离散化)
2017-04-11 13:49
253 查看
题目大意
区间长度为n,操作n次,在第i次操作的时候找出区间中第i小的元素的位置pos并翻转区间[i,pos],并输出位置pos。对于键值相同 的元素,初始位置靠前的优先翻转。
题解
splay裸题,每次维护最小元素键值和最小元素的指针。代码
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int maxn=int(1e5)+11, inf=int(1e9)+7; int n; int a[maxn]; pair<int,int> b[maxn]; struct Node { int key,siz,minval; bool flip; Node *ch[2],*fa,*minpos; Node(int); void maintain(); void pushdown(); int dir(int k) { if(ch[0]->siz+1==k) return -1; return k>ch[0]->siz+1; } int son() { if(fa->ch[0]==this) return 0; if(fa->ch[1]==this) return 1; return -1; } int rnk() { return ch[0]->siz+1; } }*null,*root; Node:: Node(int _):key(_) { siz=1,minval=key; minpos=this; flip=false; ch[1]=ch[0]=fa=null; } void Node:: maintain() { siz=ch[0]->siz+1+ch[1]->siz; minval=key, minpos=this; if(ch[0]->minval<minval) minval=ch[0]->minval, minpos=ch[0]->minpos; if(ch[1]->minval<minval) minval=ch[1]->minval, minpos=ch[1]->minpos; } void Node:: pushdown() { if(flip) { std::swap(ch[0],ch[1]); ch[0]->flip^=1, ch[1]->flip^=1; flip=false; } } void print(Node* cur) { if(cur==null) return; cur->pushdown(); print(cur->ch[0]); //cout<<cur->key<<" "; print(cur->ch[1]); } void init_null() { null=new Node(inf); null->siz=0; null->ch[0]=null->ch[1]=null->fa=null->minpos=null; return; } #define mid ((l+r)>>1) void build(Node* &cur,int l,int r) { if(l>r) {cur=null; return;} cur=new Node(a[mid]); build(cur->ch[0],l,mid-1), cur->ch[0]->fa=cur; build(cur->ch[1],mid+1,r), cur->ch[1]->fa=cur; cur->maintain(); } #undef mid void Rotate(Node* cur,int dir) { Node* tmp=cur->ch[dir^1]; cur->ch[dir^1]=tmp->ch[dir], tmp->ch[dir]->fa=cur; tmp->ch[dir]=cur; cur->maintain(), tmp->maintain(); if(~cur->son()) cur->fa->ch[cur->son()]=tmp; tmp->fa=cur->fa, cur->fa=tmp; } void Pushdown(Node* cur) { if(cur->fa!=null) Pushdown(cur->fa); cur->pushdown(); } void Splay(Node* cur) { Pushdown(cur); while(~cur->son()) { int dir=cur->son(); if(dir==cur->fa->son()) Rotate(cur->fa->fa,dir^1); Rotate(cur->fa,dir^1); } } Node* _find(Node* cur,int k) { cur->pushdown(); int dir=cur->dir(k); if(dir==1) k-=cur->ch[0]->siz+1; if(dir==-1) return cur; else return _find(cur->ch[dir],k); } Node* Merge(Node* lhs,Node* rhs) { if(lhs==null) return rhs; if(rhs==null) return lhs; Node* tmp=_find(lhs,lhs->siz); Splay(tmp); tmp->ch[1]=rhs, rhs->fa=tmp, rhs->maintain(); return tmp; } void Split(Node* org,int k,Node* &lhs,Node* &rhs) { if(k==0) { lhs=null, rhs=org; return; } else if(k==org->siz) { lhs=org, rhs=null; return; } Node *tmp=_find(org,k); Splay(tmp); lhs=tmp, rhs=tmp->ch[1]; rhs->fa=null, lhs->ch[1]=null, lhs->maintain(); return; } void Reverse(int l,int r) { if(l==r) return; Node *lhs,*tmp,*mid,*rhs; Split(root,l-1,lhs,mid); Split(mid,r-l+1,mid,rhs); mid->flip^=1; root=Merge(Merge(lhs,mid),rhs); return; } void Delete(int pos) { Node *lhs,*mid,*rhs; Split(root,pos-1,lhs,mid); Split(mid,1,mid,rhs); root=Merge(lhs,rhs); } int Get_rnk(Node* cur) { Splay(cur); int res=cur->ch[0]->siz+1; Splay(root); return res; } int main() { #ifndef ONLINE_JUDGE freopen("sort0.in","r",stdin); freopen("output.txt","w",stdout); #endif // ONLINE_JUDGE init_null(); root=null; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); b[i]=make_pair(a[i],i); } sort(b+1,b+1+n); for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+n,make_pair(a[i],i))-b; build(root,1,n); for(int i=1;i<=n;i++) { if(i>1) putchar(' '); int pos=Get_rnk(root->minpos); Reverse(1,pos); printf("%d",pos+i-1); Delete(1); } putchar('\n'); return 0; }
相关文章推荐
- bzoj 1552: [Cerc2007]robotic sort && bzoj 3506: [Cqoi2014]排序机械臂(splay区间翻转)
- 【bzoj3506/1552】【robotic sort】【splay】
- 【BZOJ】3506 [Cerc2007]robotic sort Splay
- 【bzoj 1552】【bzoj 3506】排序机械臂robotic sort(Splay)
- BZOJ 3506 robotic sort (splay)
- 【BZOJ-1552&3506】robotic sort&排序机械臂 Splay
- BZOJ_1552_[Cerc2007]robotic sort_splay
- HDU1890 Robotic Sort(Splay)
- HDU 1890 Robotic Sort | Splay
- HDU 1890 Robotic Sort (Splay)
- hdu 1890 Robotic Sort(Splay应用)
- HDU1890 Robotic Sort[splay 序列]
- 【HDU】1890 Robotic Sort 翻转区间【splay】
- hdu 1890 Robotic Sort(Splay)
- HDU 1890 Robotic Sort(Splay 区间翻转)
- hdu-1890-Robotic Sort splay区间翻转
- hdu 1890 Robotic Sort (Splay区间翻转)
- hdu 1890 Robotic Sort (Splay树)
- bzoj 1552: [Cerc2007]robotic sort(splay)
- HDU1890-Robotic Sort-Splay