• BZOJ1552: [Cerc2007]robotic sort


    1552: [Cerc2007]robotic sort

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 1428  Solved: 563
    [Submit][Status][Discuss]

    Description

    Input

    输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。
    第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。

    Output

    输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,Pi表示第i次操作前第i小的物品所在的位置。 
    注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。

    Sample Input

    6
    3 4 5 1 6 2

    Sample Output

    4 6 4 5 6 6

    HINT

    Source

    【题解】

    顺便维护一下子树最小值所在splay的节点即可,想知道节点在序列中的位置,把它splay到根看左子树即可

    需要离散化让相等的数按出现顺序从小到大排

      1 /**************************************************************
      2     Problem: 1552
      3     User: 33511595
      4     Language: C++
      5     Result: Accepted
      6     Time:3360 ms
      7     Memory:21528 kb
      8 ****************************************************************/
      9  
     10 #include <iostream>
     11 #include <cstdio>
     12 #include <cstring>
     13 #include <cstdlib>
     14 #include <algorithm>
     15 #include <queue>
     16 #include <vector>
     17 #include <map>
     18 #include <string> 
     19 #include <cmath> 
     20 #define min(a, b) ((a) < (b) ? (a) : (b))
     21 #define max(a, b) ((a) > (b) ? (a) : (b))
     22 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
     23 template <class T>
     24 inline void swap(T& a, T& b)
     25 {
     26     T tmp = a;a = b;b = tmp;
     27 }
     28 inline void read(int &x)
     29 {
     30     x = 0;char ch = getchar(), c = ch;
     31     while(ch < '0' || ch > '9') c = ch, ch = getchar();
     32     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
     33     if(c == '-') x = -x;
     34 }
     35  
     36 const int INF = 0x3f3f3f3f;
     37 const int MAXN = 500000 + 10;
     38  
     39 int ch[MAXN][2], fa[MAXN], n, root, size[MAXN], data[MAXN], mi[MAXN], tag[MAXN];
     40 void ddfs(int x)
     41 {
     42     if(!x) return;
     43     ddfs(ch[x][0]);
     44     if(x != 1 && x != n + 2) printf("%d ", data[x]);
     45     ddfs(ch[x][1]);
     46 }
     47 int son(int x){return x == ch[fa[x]][1];}
     48 void pushup(int rt)
     49 {
     50     int l = ch[rt][0], r = ch[rt][1];
     51     size[rt] = size[l] + size[r] + 1;
     52     if(mi[l] == 0) mi[rt] = mi[r];
     53     else if(mi[r] == 0) mi[rt] = mi[l];
     54     else mi[rt] = data[mi[l]] < data[mi[r]] ? mi[l] : mi[r];
     55     mi[rt] = data[mi[rt]] < data[rt] ? mi[rt] : rt;
     56 }
     57 void pushdown(int rt)
     58 {
     59     if(!tag[rt]) return;
     60     int l = ch[rt][0], r = ch[rt][1];
     61     tag[l] ^= 1, tag[r] ^= 1;
     62     swap(ch[l][0], ch[l][1]), swap(ch[r][0], ch[r][1]);
     63     tag[rt] = 0;
     64 }
     65 void rotate(int x)
     66 {
     67     int y = fa[x], z = fa[y], b = son(x), c = son(y), a = ch[x][!b];
     68     if(z) ch[z][c] = x; else root = x; fa[x] = z;
     69     if(a) fa[a] = y; ch[y][b] = a;
     70     ch[x][!b] = y, fa[y] = x;
     71     pushup(y), pushup(x);
     72 }
     73 void dfs(int x)
     74 {
     75     if(!x) return;
     76     dfs(fa[x]);
     77     pushdown(x);
     78 }
     79 void splay(int x, int i)
     80 {
     81     dfs(x);
     82     while(fa[x] != i)
     83     {
     84         int y = fa[x], z = fa[y];
     85         if(z == i) rotate(x);
     86         else
     87             if(son(x) == son(y)) rotate(y), rotate(x);
     88             else rotate(x), rotate(x); 
     89     }
     90 }
     91 int getkth(int rt, int x)
     92 {
     93     pushdown(rt);int l = ch[rt][0];
     94     if(size[l] + 1 == x) return rt;
     95     if(x < size[l] + 1) return getkth(ch[rt][0], x);
     96     return getkth(ch[rt][1], x - size[l] - 1);
     97 }
     98 void turn(int l, int r)
     99 {
    100     l = getkth(root, l - 1), r = getkth(root, r + 1);
    101 //  ddfs(root), putchar('
    '); 
    102     splay(l, 0), splay(r, l);
    103 //  ddfs(root), putchar('
    '); 
    104     int now = ch[r][0];
    105     tag[now] ^= 1;swap(ch[now][0], ch[now][1]);pushdown(now);
    106 }
    107 //查询节点k的排名 
    108 int getk(int k)
    109 {
    110     splay(k, 0);
    111     return size[ch[k][0]] + 1;
    112 }
    113 int ask_mi(int l, int r)
    114 {
    115     l = getkth(root, l - 1), r = getkth(root, r + 1);
    116 //  ddfs(root), putchar('
    '); 
    117     splay(l, 0), splay(r, l);
    118 //  ddfs(root), putchar('
    '); 
    119     return getk(mi[ch[r][0]]);
    120 }
    121  
    122 int cnt[MAXN];
    123 bool cmp(int a, int b)
    124 {
    125     return data[a] < data[b];
    126 }
    127  
    128  
    129 int main()
    130 {
    131     memset(data, 0x3f, sizeof(data));
    132     read(n);
    133     for(int i = 2;i <= n + 1;++ i) cnt[i] = i, read(data[i]);
    134     std::stable_sort(cnt + 2, cnt + 2 + n, cmp);
    135     for(int i = 2;i <= n + 1;++ i) data[cnt[i]] = i; 
    136     fa[2] = 1, ch[1][1] = 2;size[1] = n + 2;mi[1] = 2;
    137     for(int i = 2;i <= n + 1;++ i) 
    138     { 
    139         ch[i][1] = i + 1, fa[i + 1] = i;size[i] = n + 3 - i;
    140         mi[i] = i;
    141     } 
    142     size[n + 2] = 1;mi[n + 2] = n + 2;root = 1;
    143     for(int i = n + 2;i >= 1;-- i) pushup(i);
    144     for(int i = 1;i < n;++ i) 
    145     {
    146         int tmp = ask_mi(i + 1, n + 1);
    147         printf("%d ", tmp - 1);
    148         turn(i + 1, tmp);
    149     }
    150     int tmp = ask_mi(n + 1, n + 1);
    151     printf("%d
    ", tmp - 1);
    152     return 0;
    153 }
    BZOJ1552
  • 相关阅读:
    编程实现折半法查找
    浅谈C++多态性
    纯虚函数的使用汇总
    虚函数如何实现多态 ?
    重载(overload),覆盖(override),隐藏(hide)的区别
    Qt入门之常用Qt标准对话框之QMessageBox
    Qt5学习笔记(5)——列表框QListWidget类
    python 文件的方法
    python---while循环
    python ---strip()方法,split()方法,删除字符串开头或结尾,字符串分隔
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8375749.html
Copyright © 2020-2023  润新知