• BZOJ1552 [Cerc2007]robotic sort


    支持区间最小值查询,区间翻转的数据结构

    直接上treap板子啊亲!没了。。。

    只是为了存板用的2333

      1 /**************************************************************
      2     Problem: 1552
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:2456 ms
      7     Memory:5572 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <algorithm>
     12  
     13 using namespace std;
     14 const int N = 1e5 + 5;
     15 const int inf = 1e9;
     16  
     17 inline int read();
     18 inline void print(int, char);
     19  
     20 int n, a[N];
     21  
     22 namespace treap {
     23     struct node;
     24     node *null, *root;
     25      
     26     struct node {
     27         node *ls, *rs;
     28         int sz, v;
     29         bool rev;
     30         int mn, wmn;
     31          
     32         node() {}
     33         node (int _v) : v(_v) {
     34             ls = rs = null;
     35             rev = 0, sz = 1;
     36             mn = _v, wmn = -1;
     37         }
     38          
     39         #define Len (1 << 16)
     40         void* operator new(size_t, int _v) {
     41             static node *mempool, *c;
     42             if (c == mempool)
     43                 mempool = (c = new node[Len]) + Len;
     44             *c = node(_v);
     45             return c++;
     46         }
     47         #undef Len
     48          
     49         inline void push() {
     50             if (rev) {
     51                 swap(ls, rs);
     52                 ls -> rev ^= 1, rs -> rev ^= 1;
     53                 if (wmn != -1) wmn ^= 1;
     54                 rev = 0;
     55             }
     56         }
     57         inline void update() {
     58             sz = ls -> sz + rs -> sz + 1;
     59             wmn = -1, mn = v;
     60             if (ls -> mn <= mn) wmn = 0, mn = ls -> mn;
     61             if (rs -> mn < mn) wmn = 1, mn = rs -> mn;
     62         }
     63     };
     64      
     65     inline unsigned int rand() {
     66         static unsigned int res = 2333;
     67         return res += res << 2 | 1;
     68     }
     69     inline int random(int x, int y) {
     70         return rand() % (x + y) < x;
     71     }
     72      
     73     void build(node *&p, int *a, int l, int r) {
     74         if (l > r) return;
     75         p = new(a[l + r >> 1])node;
     76         if (l == r) return;
     77         build(p -> ls, a, l, (l + r >> 1) - 1);
     78         build(p -> rs, a, (l + r >> 1) + 1, r);
     79         p -> update();
     80     }
     81      
     82     void merge(node *&p, node *x, node *y) {
     83         if (x == null || y == null) {
     84             p = x == null ? y : x;
     85             p -> update();
     86             return;
     87         }
     88         if (random(x -> sz, y -> sz)) {
     89             x -> push(), p = x;
     90             merge(p -> rs, x -> rs, y);
     91             p -> update();
     92         } else {
     93             y -> push(), p = y;
     94             merge(p -> ls, x, y -> ls);
     95             p -> update();
     96         }
     97     }
     98      
     99     void split(node *p, node *&x, node *&y, int k) {
    100         if (!k) {
    101             x = null, y = p;
    102             return;
    103         }
    104         if (k == p -> sz) {
    105             x = p, y = null;
    106             return;
    107         }
    108         p -> push();
    109         if (p -> ls -> sz >= k) {
    110             y = p;
    111             split(p -> ls, x, y -> ls, k);
    112             y -> update();
    113         } else {
    114             x = p;
    115             split(p -> rs, x -> rs, y, k - p -> ls -> sz - 1);
    116             x -> update();
    117         }
    118     }
    119      
    120     inline void reverse(int l, int r) {
    121         static node *x, *y, *z;
    122         split(root, x, z, l - 1);
    123         split(z, y, z, r - l + 1);
    124         y -> rev ^= 1;
    125         root = x;
    126         merge(root, root, y);
    127         merge(root, root, z);
    128     }
    129      
    130     inline int get_min(node *p) {
    131         p -> push();
    132         if (p -> wmn == 0) return get_min(p -> ls);
    133         if (p -> wmn == -1) return p -> ls -> sz + 1;
    134         return p -> ls -> sz + 1 + get_min(p -> rs);
    135     }
    136     inline void modify(node *p, int k, int _v) {
    137         p -> push();
    138         if (p -> ls -> sz + 1 == k) p -> v = _v;
    139         else if (p -> ls -> sz >= k) modify(p -> ls, k, _v);
    140         else modify(p -> rs, k - p -> ls -> sz - 1, _v);   
    141         p -> update();
    142     }
    143 };
    144  
    145 int tmp[N], tmp2[N];
    146 inline bool cmp(int x, int y) {
    147     return tmp[x] == tmp[y] ? x < y : tmp[x] < tmp[y];
    148 }
    149  
    150 int main() {
    151     int i, x;
    152     using namespace treap;
    153     n = read();
    154     for (i = 1; i <= n; ++i) tmp[i] = read(), tmp2[i] = i;
    155     sort(tmp2 + 1, tmp2 + n + 1, cmp);
    156     for (i = 1; i <= n; ++i) a[tmp2[i]] = i;
    157     null = new(inf)node;
    158     null -> ls = null -> rs = null, null -> sz = 0;
    159     build(root, a, 1, n);
    160     for (i = 1; i <= n; ++i) {
    161         print(x = get_min(root), i == n ? '
    ' : ' ');
    162         reverse(i, x);
    163         modify(root, i, inf);
    164     }
    165     return 0;
    166 }
    167  
    168 inline int read() {
    169     static int x;
    170     static char ch;
    171     x = 0, ch = getchar();
    172     while (ch < '0' || '9' < ch)
    173         ch = getchar();
    174     while ('0' <= ch && ch <= '9') {
    175         x = x * 10 + ch - '0';
    176         ch = getchar();
    177     }
    178     return x;
    179 }
    180  
    181 inline void print(int t, char ch = ' ') {
    182     static int tot, pr[10];
    183     tot = 0;
    184     while (t)
    185         pr[++tot] = t % 10, t /= 10;
    186     if (!tot) putchar('0');
    187     while (tot) putchar(pr[tot--] + '0');
    188     putchar(ch);
    189 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    PHP isset()和empty()区别
    C++ 需要注意的知识点
    Unreal Engine:Socket源码解析
    Unreal Engine:动态内存和智能指针
    K8S 如何重启 Pod
    如何使用 nginx 对后端服务做主备
    K8S 集群安装 metalLB 使用 EIP
    Centos 7 系统安装后初始化操作
    K8S v1.20 及以上版本 StorageClass 创建 PVC 不成功解决
    K8S 如何查看 pod 中的容器
  • 原文地址:https://www.cnblogs.com/rausen/p/4471202.html
Copyright © 2020-2023  润新知