zoukankan      html  css  js  c++  java
  • HDU 1890 Robotic Sort(splay)

    【题目链接】

        http://acm.hdu.edu.cn/showproblem.php?pid=1890

    【题意】

        给定一个序列,每次将i..P[i]反转,然后输出P[i],P[i]定义为当前数字i的所在位置。相等的两个数排序后相对位置不变。

    【思路】

        由于相对位置不变,所以可以根据数值与位置重编号。

        依旧使用直接定位从上到下旋转至根的splay写法。每次将i结点旋转至根,则答案为左儿子大小+i,然后将i删掉合并左右儿子。

        需要注意合并时判断左右儿子是否为空,以及各种pushdown下传标记。

    【代码】

      1 #include<set>
      2 #include<cmath>
      3 #include<queue>
      4 #include<vector>
      5 #include<cstdio>
      6 #include<cstring>
      7 #include<iostream>
      8 #include<algorithm>
      9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
     10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
     11 using namespace std;
     12 
     13 typedef long long ll;
     14 const int N = 5e5+10; 
     15 
     16 ll read() {
     17     char c=getchar();
     18     ll f=1,x=0;
     19     while(!isdigit(c)) {
     20         if(c=='-') f=-1; c=getchar();
     21     }
     22     while(isdigit(c))
     23         x=x*10+c-'0',c=getchar();
     24     return x*f;
     25 }
     26 
     27 struct Node *null;
     28 struct Node {
     29     int v,s,rev;
     30     Node *ch[2],*fa;
     31     void init(int x) {
     32         v=x;
     33         s=rev=0;
     34         ch[0]=ch[1]=fa=null;
     35     }
     36     void pushdown() {
     37         if(rev) {
     38             swap(ch[0],ch[1]);
     39             ch[0]->rev^=1; ch[1]->rev^=1;
     40             rev=0;
     41         }
     42     }
     43     void maintain() {
     44         s=ch[0]->s+ch[1]->s+1;
     45     }
     46 } nodepool[N],*node[N];
     47 
     48 void rot(Node* o,int d) {
     49     Node *k=o->ch[d],*tmp=null;
     50     o->ch[d]=k->ch[d^1];
     51     if((tmp=k->ch[d^1])!=null) tmp->fa=o;
     52     k->ch[d^1]=o;
     53     if((tmp=o->fa)!=null) tmp->ch[tmp->ch[1]==o]=k;
     54     o->fa=k; k->fa=tmp;
     55 }
     56 Node *st[N<<3];
     57 void up_push(Node* u) {
     58     int top=0;
     59     while(u!=null) 
     60         st[++top]=u,u=u->fa;
     61     while(top) 
     62         st[top--]->pushdown();
     63 }
     64 void splay(Node* o,Node* des=null) {
     65     up_push(o);
     66     Node *nf,*nff;
     67     while(o!=des && (nf=o->fa)!=des) {
     68         nff=nf->fa;
     69         if(nff==des) rot(nf,nf->ch[1]==o),nf->maintain();
     70         else {
     71             int d1=nf->ch[1]==o,d2=nff->ch[1]==nf;
     72             if(d1==d2) rot(nff,d2),rot(nf,d1);
     73             else rot(nf,d1),rot(nff,d2);
     74             nff->maintain(),nf->maintain();
     75         }
     76     }
     77     o->maintain();
     78 }
     79 void reverse(Node* o) {
     80     swap(o->ch[0],o->ch[1]);
     81     o->ch[0]->rev^=1;
     82     o->ch[1]->rev^=1;
     83 }
     84 Node* getbound(Node* o,int d) {
     85     o->pushdown();
     86     if(o->ch[0]==null&&o->ch[1]==null) return o;
     87     if(o->ch[d]!=null) return getbound(o->ch[d],d);
     88     else return o;
     89 }
     90 void merge(Node* u,Node* v) {
     91     if(u->ch[1]==null) u->ch[1]=v;
     92     else {
     93         u=getbound(u,1);
     94         splay(u);
     95         u->ch[1]=v;    
     96     }
     97     v->fa=u; u->maintain();
     98 }
     99 
    100 int n,a[N];
    101 
    102 Node* build(int l,int r,Node* fa) {
    103     if(l>r) return null;
    104     int mid=l+r>>1;
    105     Node* o=node[a[mid]];
    106     o->fa=fa;
    107     o->v=a[mid];
    108     o->ch[0]=build(l,mid-1,o);
    109     o->ch[1]=build(mid+1,r,o);
    110     o->maintain();
    111     return o;
    112 }
    113 struct snode {
    114     int a,rank;
    115     bool operator < (const snode& rhs) const {
    116         return a<rhs.a||(a==rhs.a&&rank<rhs.rank);
    117     }
    118 } nodes[N];
    119 
    120 int main()
    121 {
    122     //freopen("in.in","r",stdin);
    123     //freopen("out.out","w",stdout);
    124     while(n=read(),n) {
    125         null=new Node();
    126         FOR(i,1,n) {
    127             a[i]=read();
    128             nodes[i]=(snode){a[i],i};
    129             node[i]=&nodepool[i];
    130             nodepool[i].init(0);
    131         }
    132         sort(nodes+1,nodes+n+1);
    133         FOR(i,1,n) a[nodes[i].rank]=i;
    134         build(1,n,null);
    135         FOR(i,1,n-1) {
    136             Node* o=node[i];
    137             splay(o);
    138             printf("%d ",o->ch[0]->s+i);
    139             Node *lc=o->ch[0],*rc=o->ch[1];
    140             o->ch[0]=o->ch[1]=null;
    141             lc->fa=rc->fa=null;
    142             if(lc!=null) {
    143                 lc->pushdown(); 
    144                 if(rc!=null) rc->pushdown();
    145                 reverse(lc);
    146                 merge(lc,rc);
    147             }
    148         }
    149         printf("%d
    ",n);
    150     }
    151     return 0;
    152 }

    P.S.好久之前就想切掉这道题了,但一直苦于没有正确的姿势=-=

  • 相关阅读:
    盒子的display属性
    html标签默认属性值之margin;padding值
    JS事件
    表单序列化
    2016年最后一天——前端心语
    原生JS--COOKIE
    原生JS--Ajax
    DOM,BOM
    JS面向对象
    RegExp类型,单体内置对象
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5294702.html
Copyright © 2011-2022 走看看