HDU 1890 Robotic Sort
来源:互联网 发布:七微的小说南风知我意2 编辑:程序博客网 时间:2024/05/17 02:46
试水splay
思路:把需要排的的节点splay到根(预处理保存这些节点),就可得到答案(左子树节点的数量)
更新的时候就是把当前序列第ith个节点splay到根,刚需要排的节点splay到根的右子树,跟新根的右子树的左子树
题外话: 一开始写的时候傻了,硬是自己去找到当前要排序的节点,然后splay到根。 还有自己写的一些函数忘记pushdown了。。。
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn = 1e5+100;const int inf = 0x7FFFFFFF;struct Snode{ Snode *p,*c[2]; int key,sz; bool rev; bool getlr(){return p->c[1]==this;} Snode *link(int w,Snode *x,Snode *null){c[w]=x; if(x!=null) x->p=this; return this;}}S[maxn],*sa[maxn],*root,*null;struct node{ int x,n;}a[maxn];int n,tot,pos[maxn];bool cmp1(node a,node b){ if(a.x == b.x) return a.n<b.n; return a.x<b.x;}bool cmp2(node a,node b){ return a.n < b.n;}Snode *NewNode(int key, Snode *p){ Snode *e = S + ++tot; e->key = key; e->p = p; e->sz = 1; e->rev = 0; e->c[0] = e->c[1] = null; return e;}void Update_Rev(Snode *x){ if(x==null) return; swap(x->c[0],x->c[1]); x->rev ^= 1;}void pushup(Snode *x){ if(x==null) return; x->sz = x->c[0]->sz + x->c[1]->sz + 1;}void pushdown(Snode *x){ if(x==null) return; if(x->rev) { Update_Rev(x->c[0]); Update_Rev(x->c[1]); x->rev = 0; }}void rot(Snode *x){ Snode *q = x->p->p; int o = x->getlr(); x->link(!o, x->p->link(o, x->c[!o], null), null); pushup(x->p); if(q!=null) q->link(q->c[1]==x->p, x, null); else {x->p = null;root = x;}}void splay(Snode *x, Snode *tar){ while(x->p!=tar && x->p->p!=tar) { pushdown(x->p->p); pushdown(x->p); pushdown(x); x->getlr()==x->p->getlr()?rot(x->p):rot(x),rot(x); } if(x->p!=tar) { pushdown(x->p); pushdown(x); rot(x); } pushup(x);}Snode* succ(Snode *x) //寻找后继{ if(x==null) return null; pushdown(x); x = x->c[1]; pushdown(x); while(x->c[0] != null) {x = x->c[0]; pushdown(x);} return x;}#define lsz x->c[0]->szvoid select(int k, Snode *y){ Snode *x = root; pushdown(x); while(lsz + 1 != k) { if(k<=lsz) x=x->c[0]; else { k -= lsz + 1; x = x->c[1]; } pushdown(x); } splay(x, y);}Snode* build(int l,int r,Snode *p){ if(l > r) return null; int m = (l+r)/2; Snode *x = NewNode(a[m].x,p); sa[pos[m]] = x; x->c[0] = build(l,m-1,x); x->c[1] = build(m+1,r,x); pushup(x); return x;}void Reserve(int L){ Snode *x = succ(root); select(L, null); splay(x, root); Update_Rev(root->c[1]->c[0]); splay(root->c[1]->c[0], null);}void init(){ tot = 0; null = NewNode(inf, 0); null->c[0] = null->c[1] = null; null->sz = 0; root = null;}int main(){ while(scanf("%d",&n),n) { init(); a[0].x = pos[0] = a[n+1].x = pos[n+1] =maxn-1; for(int i=1;i<=n;i++) { scanf("%d",&a[i].x); a[i].n = i; } sort(a+1,a+n+1,cmp1); for(int i=1;i<=n;i++) pos[a[i].n] = i; sort(a+1,a+n+1,cmp2); root = build(0, n+1, null); for(int i=1;i<=n;i++) { splay(sa[i], null); printf("%d%s",root->c[0]->sz,i==n?"\n":" "); Reserve(i); } } return 0;}
0 0
- HDU 1890 Robotic Sort
- HDU 1890 Robotic Sort
- hdu 1890 Robotic Sort
- hdu 1890 Robotic Sort
- HDU 1890 Robotic Sort
- hdu-1890 Robotic Sort
- hdu 1890 Robotic Sort(treap)
- HDU 1890 Robotic Sort(SplayTree)
- 【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 tree
- HDU 1890 Robotic Sort(Splay tree)
- hdu 1890 Robotic Sort(Splay应用)
- hdu 1890 Robotic Sort (Splay树)
- hdu 1890 Robotic Sort(Splay)
- hdu 1890 Robotic Sort(伸展树)
- Structured Learning和Structured SVM的学习(上)
- MAVEN常用命令
- 将两个有序链表合并成一个有序链表
- Android 开源项目源码分析第一期正式发布
- Linux命令学习:用户管理(中)
- HDU 1890 Robotic Sort
- Linux命令学习:用户管理(下)
- bzoj1066
- Telnet Linux
- php绝对路径与相对路径之间关系的的深入研究
- 《Java并发编程实战》读书笔记·Part1
- 【ACM打卡】3174
- 需求调研的几个误区
- 函数