zoukankan      html  css  js  c++  java
  • bzoj 3506[Cqoi2014]排序机械臂

            3506: [Cqoi2014]排序机械臂

    题目描述

    为了把工厂中高低不等的物品按从低到高排好序,工程师发明了一种排序机械臂。它遵循一个简单的排序规则,第一次操作找到高度最低的物品的位置 P_1P1 ,并把左起第一个物品至 P_1P1 间的物品 (即区间 [1,P_1][1,P1] 间的物品) 反序;第二次找到第二低的物品的位置 P_2P2 ,并把左起第二个至 P_2P2 间的物品 (即区间 [2,P_2][2,P2] 间的物品) 反序……最终所有的物品都会被排好序。

    样例说明

    上图给出有六个物品的示例,第一次操作前,高度最低的物品在位置 44 ,于是把第一至第四的物品反序;第二次操作前,第二低的物品在位罝六,于是把第二至六的物品反序……

    你的任务便是编写一个程序,确定一个操作序列,即每次操作前第 ii 低的物品所在位置 P_iPi ,以便机械臂工作。需要注意的是,如果有高度相同的物品,必须保证排序后它们的相对位置关系与初始时相同。

    输入输出格式

    输入格式:

    第一行包含正整数n,表示需要排序的物品数星。

    第二行包含n个空格分隔的整数ai,表示每个物品的高度。

    输出格式:

    输出一行包含n个空格分隔的整数Pi。

    输入输出样例

    输入样例#1:

    6
    3 4 5 1 6 2

    输出样例#1: 

    4 6 4 5 6 6

    HINT

    N<=100000

    Pi<=10^7

    维护一个数列,支持区间翻转,所以可以用SPLAY来维护

    我们可以先将数排序,这样他们节点数组的下标对应的就是排名

    然后就是区间翻转的操作

    注意SPLAY的时候要先pushdown

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 #define LL long long
      6 #define lc t[x].ch[0] 
      7 #define rc t[x].ch[1]
      8 using namespace std;
      9 
     10 const int MAXN = 2e5 + 10;
     11 
     12 LL ans = 0;
     13 int sum = 0;
     14 int n;
     15 int root;
     16 int loc[MAXN];
     17 struct node {
     18     int size;
     19     int val;
     20     int id;
     21     int fa;
     22     int ch[2];
     23     int lazy;
     24 } t[MAXN];
     25 
     26 void pushdown(int x)
     27 {
     28     if(t[x].lazy) {
     29         swap(lc, rc);
     30         t[lc].lazy ^= 1;
     31         t[rc].lazy ^= 1;
     32         t[x].lazy ^= 1;
     33     }
     34 }
     35 
     36 void pushup(int x)
     37 {
     38     t[x].size = t[lc].size + t[rc].size + 1;
     39 }
     40 inline LL read()
     41 {
     42     LL x = 0, w = 1; char ch = 0;
     43     while(ch < '0' || ch > '9') {
     44         if(ch == '-') {
     45             w = -1;
     46         }
     47         ch = getchar();
     48     }
     49     while(ch >= '0' && ch <= '9') {
     50         x = x * 10 + ch - '0';
     51         ch = getchar();
     52     }
     53     return x * w;
     54 }
     55 
     56 void rotate(int x, int &k)
     57 {
     58     int y = t[x].fa, z = t[y].fa;
     59     int l, r;
     60     if(y == k) {
     61         k = x;
     62     } else {
     63         if(t[z].ch[0] == y) {
     64             t[z].ch[0] = x;
     65         } else {
     66             t[z].ch[1] = x;
     67         }
     68     }
     69     if(t[y].ch[0] == x) {
     70         l = 0;
     71     } else {
     72         l = 1;
     73     }
     74     r = l ^ 1;
     75     t[y].ch[l] = t[x].ch[r], t[t[x].ch[r]].fa = y;
     76     t[x].fa = z, t[y].fa = x, t[x].ch[r] = y;
     77     pushup(y);
     78     pushup(x);
     79 }
     80 
     81 void splay(int x, int &k)
     82 {
     83     while(x != k) {
     84         int y = t[x].fa, z = t[y].fa;
     85         if(y != k) {
     86             if((t[z].ch[0] == y) ^ (t[y].ch[0] == x)) {
     87                 rotate(x, k);
     88             } else {
     89                 rotate(y, k);
     90             }
     91         }
     92         rotate(x, k);
     93     }
     94 }
     95 
     96 int query(int k, int x)
     97 {
     98     pushdown(x);
     99     while(t[lc].size + 1 != k) {
    100         if(t[lc].size >= k) {
    101             x = lc;    
    102         } else {
    103             k = k - t[lc].size - 1;
    104             x = rc;
    105         }
    106         pushdown(x);
    107     }
    108     return x;
    109 }
    110 
    111 bool cmp(node a, node b)
    112 {
    113     if(a.val == b.val) {
    114         return a.id < b.id;
    115     }
    116     return a.val < b.val;
    117 }
    118 
    119 void build(int l, int r, int &x, int last)
    120 {
    121     if(l > r) {
    122         x = 0;
    123         return;
    124     }
    125     int mid = (l + r) >> 1;
    126     x = loc[mid];
    127     t[x].fa = last;
    128     build(l, mid - 1, lc, x);
    129     build(mid + 1, r, rc, x);
    130     pushup(x);
    131 }
    132 
    133 void push(int x)
    134 {
    135     int sum = 0;
    136     if(t[x].fa) {
    137         push(t[x].fa);
    138         pushdown(x);
    139     }
    140 }
    141 
    142 void print(int x)
    143 {
    144     cout<<x<<" "<<t[x].size<<" "<<lc<<" "<<rc<<endl;
    145     if(lc) {
    146         print(lc);
    147     }
    148     if(rc) {
    149         print(rc);
    150     }
    151 }
    152 
    153 int main()
    154 {
    155     n = read();
    156     for(int i = 1; i <= n; i++) {
    157         t[i].id = i;
    158         t[i].val = read();
    159     }
    160     sort(t + 1, t + n + 1, cmp);
    161     for(int i = 1; i <= n; i++) {
    162         loc[t[i].id] = i;
    163     }
    164     loc[0] = n + 2, loc[n + 1] = n + 1;
    165     build(0, n + 1, root, 0);
    166     for(int i = 1; i <= n; i++) {
    167         push(i);
    168         splay(i, root);
    169         ans = t[t[root].ch[0]].size;
    170         printf("%lld ", ans);
    171         int loc = query(i, root);
    172         splay(loc, root);
    173         loc = query(ans + 2, root);
    174         splay(loc, t[root].ch[1]);
    175         t[t[loc].ch[0]].lazy ^= 1;
    176     }
    177     return 0;
    178 }
    179 
    180 
    181 /*
    182 6
    183 3 4 5 1 6 2
    184 
    185 */ 
    View Code
  • 相关阅读:
    alt属性和title属性
    穷人和富人的区别
    JS经典源码:通用JavaScript脚本函数库
    网页弹出框
    男女交往必知15个真理
    alexa排名
    好男人找不到女朋友的根源
    小笑话集(全是经典!)不信你不笑(转)
    送到家服务网2009年3月26日顺利上线了!
    [转]互联网产品开发中的“快”字诀
  • 原文地址:https://www.cnblogs.com/wuenze/p/8653172.html
Copyright © 2011-2022 走看看