zoukankan      html  css  js  c++  java
  • [BZOJ1552] [Cerc2007] robotic sort (splay)

    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

      HNOI2009集训Day6

    Solution

      预处理$[1, n]$中所有数的位置,每次把当前查找的数$x$旋到根上,其左儿子的子树大小就是答案。再对题意所述的区间加个reverse标记即可。

      因为有区间加标记,所以最好加上头尾两个虚拟节点。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 struct spaly
     4 {
     5     int c[2], fa, siz, rev;
     6 }a[100005];
     7 pair<int, int> b[100005];
     8  
     9 void push_up(int k)
    10 {
    11     a[k].siz = a[a[k].c[0]].siz + a[a[k].c[1]].siz + 1;
    12 }
    13  
    14 void push_down(int k)
    15 {
    16     if(a[k].rev)
    17     {
    18         swap(a[k].c[0], a[k].c[1]), a[k].rev = 0;
    19         a[a[k].c[0]].rev ^= 1, a[a[k].c[1]].rev ^= 1;
    20     }
    21 }
    22  
    23 void rotate(int &k, int x)
    24 {
    25     int y = a[x].fa, z = a[y].fa;
    26     int dy = a[y].c[1] == x, dz = a[z].c[1] == y;
    27     if(k == y) k = x, a[x].fa = z;
    28     else a[z].c[dz] = x, a[x].fa = z;
    29     a[y].c[dy] = a[x].c[!dy], a[a[x].c[!dy]].fa = y;
    30     a[x].c[!dy] = y, a[y].fa = x;
    31     push_up(y);
    32 }
    33  
    34 void splay(int &k, int x)
    35 {
    36     while(k != x)
    37     {
    38         int y = a[x].fa, z = a[y].fa;
    39         push_down(z), push_down(y), push_down(x);
    40         if(k != y)
    41             if(a[y].c[1] == x ^ a[z].c[1] == y) rotate(k, x);
    42             else rotate(k, y);
    43         rotate(k, x);
    44     }
    45     push_up(x);
    46 }
    47  
    48 int find(int k, int x)
    49 {
    50     if(!k) return 0;
    51     push_down(k);
    52     if(x <= a[a[k].c[0]].siz) return find(a[k].c[0], x);
    53     if(x == a[a[k].c[0]].siz + 1) return k;
    54     return find(a[k].c[1], x - a[a[k].c[0]].siz - 1);
    55 }
    56  
    57 int main()
    58 {
    59     int n, root, pos;
    60     while(~scanf("%d", &n) && n)
    61     {
    62         for(int i = 1; i <= n; i++)
    63         {
    64             scanf("%d", &b[i].first);
    65             b[i].second = i + 1;
    66         }
    67         sort(b + 1, b + n + 1);
    68         for(int i = 1; i <= n + 2; i++)
    69         {
    70             a[i].fa = i + 1, a[i].c[0] = i - 1;
    71             a[i].siz = i, a[i].c[1] = a[i].rev = 0;
    72         }
    73         a[n + 2].fa = 0, root = n + 2;
    74         for(int i = 1; i <= n; i++)
    75         {
    76             splay(root, b[i].second);
    77             pos = a[a[root].c[0]].siz;
    78             printf("%d", pos);
    79             if(i != n) printf(" ");
    80             splay(root, find(root, i));
    81             splay(a[root].c[1], find(root, pos + 2));
    82             a[a[a[root].c[1]].c[0]].rev ^= 1;
    83         }
    84         puts("");
    85     }
    86     return 0;
    87 }
    View Code

       双倍经验的时候到了(。・ω・)ノ゙BZOJ3506 我是雷锋我骄傲。

  • 相关阅读:
    聊聊CMDB的前世今生
    我是如何走上运维岗位的?谈谈新人入职运维发展的注意事项
    如何从生命周期的视角看待应用运维体系建设?
    标准化体系建设(下):如何建立基础架构标准化及服务化体系?
    标准化体系建设(上):如何建立应用标准化体系和模型?
    微服务架构时代,运维体系建设为什么要以“应用”为核心?
    Kubernetes容器化工具Kind实践部署Kubernetes v1.18.x 版本, 发布WordPress和MySQL
    Etcd常用运维命令
    Logstash生产环境实践手册(含grok规则示例和ELKF应用场景)
    Netflix业务运维分析和总结
  • 原文地址:https://www.cnblogs.com/CtrlCV/p/5415703.html
Copyright © 2011-2022 走看看