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

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

    题意:有一个无序序列,经过不断地翻转,使得最后的序列是一个升序的序列,而且如果相同数字要使在原本序列靠前的在前面。对于每一个位置,输出于哪个位置翻转。

    思路:想通了之后其实挺简单的,不过挺巧妙。一开始先记录每一个位的pos,并对数组升序排序,然后我们从小到大枚举数组里的元素,对于每个元素,我们可以知道:i 就是翻转后应当在序列中的位置,a[i].pos就是它在原序列的位置。这个时候,我们只要在建树的时候利用中序遍历就是原数组的样子的性质,让节点的值就是它在原数组的位置,即建一个新的节点的时候,x 就是在原数组中的编号,例如样例:3 4 5 1 6 2,那么对应的节点的值就是 1 2 3 4 5 6 了。然后对于每一个询问,我们知道了它在原序列的位置,我们将它的位置(即节点本身的值)旋转到根节点,那么它的左子树的 sz 就是它目前所在的位置(因为一开始多了一个节点),然后再对 目标位置 和 所在的位置进行区间翻转,就可以完成了。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstring>
      5 #include <string>
      6 #include <cmath>
      7 #include <queue>
      8 #include <vector>
      9 using namespace std;
     10 #define INF 0x7fffffff
     11 #define lson ch[x][0]
     12 #define rson ch[x][1]
     13 #define keytree ch[ch[root][1]][0]
     14 #define rootkey ch[root][1]
     15 #define N 300000
     16 struct node
     17 {
     18     int val, id;
     19 }a[N];
     20 struct SplayTree {
     21     int num[N], sz[N], fa[N], ch[N][2], root, rev[N];
     22     int n;
     23 
     24     void PushUp(int x) {
     25         sz[x] = sz[lson] + sz[rson] + 1;
     26     }
     27 
     28     void PushDown(int x) {
     29         if(rev[x]) {
     30             swap(lson, rson);
     31             if(lson) rev[lson] ^= 1;
     32             if(rson) rev[rson] ^= 1;
     33             rev[x] = 0;
     34         }
     35     }
     36 
     37     int NewNode(int f, int k, int kind) {
     38         int x = k;
     39         fa[x] = f;
     40         rev[x] = ch[x][0] = ch[x][1] = 0;
     41         sz[x] = 1; ch[f][kind] = x;
     42         return x;
     43     }
     44 
     45     void Build(int l, int r, int &x, int f, int kind) {
     46         if(l > r) return ;
     47         int m = (l + r) >> 1;
     48         x = NewNode(f, m, kind);
     49         Build(l, m - 1, ch[x][0], x, 0);
     50         Build(m + 1, r, ch[x][1], x, 1);
     51         PushUp(x);
     52     }
     53 
     54     void Init() {
     55         root = 0;
     56         ch[0][0] = ch[0][1] = fa[0] = rev[0] = sz[0] = 0;
     57         root = NewNode(0, n + 1, 0);
     58         rootkey = NewNode(root, n + 2, 1);
     59         sz[root] = 2;
     60         Build(1, n, keytree, rootkey, 0);
     61         PushUp(rootkey); PushUp(root);
     62     }
     63 
     64     void Rotate(int x, int kind) {
     65         int y = fa[x], z = fa[y];
     66         PushDown(y); PushDown(x);
     67         ch[y][!kind] = ch[x][kind];
     68         if(ch[x][kind]) fa[ch[x][kind]] = y;
     69         if(z) {
     70             if(y == ch[z][0]) ch[z][0] = x;
     71             else ch[z][1] = x;
     72         }
     73         fa[x] = z; fa[y] = x;
     74         ch[x][kind] = y;
     75         PushUp(y);
     76     }
     77 
     78     void Splay(int x, int goal) {
     79         PushDown(x);
     80         while(fa[x] != goal) {
     81             int y = fa[x], z = fa[y];
     82             PushDown(z); PushDown(y); PushDown(x);
     83             int kind1 = x == ch[y][0];
     84             int kind2 = y == ch[z][0];
     85             if(z == goal) {
     86                 Rotate(x, kind1);
     87             } else {
     88                 if(kind1 == kind2) Rotate(y, kind1);
     89                 else Rotate(x, kind1);
     90                 Rotate(x, kind2);
     91             }
     92         }
     93         PushUp(x);
     94         if(!goal) root = x;
     95     }
     96 
     97     void RTO(int k, int goal) {
     98         int x = root;
     99         PushDown(x);
    100         while(sz[lson] + 1 != k) {
    101             if(sz[lson] >= k) x = lson;
    102             else k -= sz[lson] + 1, x = rson;
    103             PushDown(x);
    104         }
    105         Splay(x, goal);
    106     }
    107 
    108     void Travel(int x) {
    109         if(lson) Travel(lson);
    110         printf("travel : %d
    ", x);
    111         if(rson) Travel(rson);
    112         PushUp(x);
    113     }
    114 
    115     int Suf(int x) { // 找后继
    116         if(rson) {
    117             PushDown(x);
    118             x = rson;
    119             while(lson) {
    120                 x = lson;
    121                 PushDown(x);
    122             }
    123         }
    124         return x;
    125     }
    126 
    127     int Query(int l, int r) {
    128         Splay(r, 0); // 把原来节点的位置旋转到root位置
    129         int ans = sz[ch[root][0]]; // 因为多了一个节点,所以不用+1
    130         RTO(l, 0); // 把第l个数的前一个旋到root
    131         Splay(Suf(r), root); // 把后继旋到ch[root][1]
    132         rev[keytree] ^= 1; //区间翻转
    133         return ans;
    134     }
    135 
    136 }spy;
    137 
    138 bool cmp(const node &a, const node &b) {
    139     if(a.val == b.val) return a.id < b.id;
    140     return a.val < b.val;
    141 }
    142 
    143 int main() {
    144     int n;
    145     while(scanf("%d", &n), n) {
    146         spy.n = n;
    147         for(int i = 1; i <= n; i++) {
    148             scanf("%d", &spy.num[i]);
    149             a[i].id = i;
    150             a[i].val = spy.num[i];
    151         }
    152         sort(a + 1, a + 1 + n, cmp);
    153         spy.Init();
    154         for(int i = 1; i <= n; i++) {
    155             int ans;
    156             ans = spy.Query(i, a[i].id);
    157             if(i == n) printf("%d
    ", ans);
    158             else printf("%d ", ans);
    159         }
    160     }
    161     return 0;
    162 }
  • 相关阅读:
    Ext.Msg.alert要注意的问题
    项目终于到了可以轻松下的时候,^_^
    Ext最佳应用
    Google居然无视中国人民的感情
    google的logo居然还是鲜艳色的!!!(下午已经是黑的了,还是感谢google)
    我们必须支持国产,这是义务
    管理软件更需要Open Social
    设计模式外观模式(Facade)
    设计模式代理模式(Proxy)
    设计模式桥接模式(Bridge)
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6069135.html
Copyright © 2011-2022 走看看