zoukankan      html  css  js  c++  java
  • BZOJ1861 [Zjoi2006]Book 书架

    直接模拟过程就好了,维护数列的话用平衡树即可

    注意要使用外部指针指向每个数出现的地方,否则没办法直接查找到

      1 /**************************************************************
      2     Problem: 1861
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:1088 ms
      7     Memory:4004 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11  
     12 using namespace std;
     13 const int N = 8e4 + 5;
     14  
     15 inline int read();
     16  
     17 namespace treap {
     18     struct node;
     19     node *null, *T, *ptr[N];
     20      
     21     struct node {
     22         node *ls, *rs, *fa;
     23         int v, sz;
     24          
     25         node() {}
     26         node(int _v, node *_f) {
     27             ls = rs = null, fa = _f;
     28             v = _v, sz = 1;
     29         }
     30          
     31         #define Len (1 << 16)
     32         inline void* operator new(size_t, int _v, node *_f) {
     33             static node *mempool, *c;
     34             if (mempool == c)
     35                 mempool = (c = new node[Len]) + Len;
     36             *c = node(_v, _f);
     37             return c++;
     38         }
     39         #undef Len
     40          
     41         inline void update() {
     42             sz = ls -> sz + rs -> sz + 1;
     43             ls -> fa = rs -> fa = this;
     44         }
     45     };
     46      
     47     #define mid (l + r >> 1)
     48     void build(node *&p, node *fa, int l, int r, int *a) {
     49         ptr[a[mid]] = p = new(a[mid], fa)node;
     50         if (l < mid) build(p -> ls, p, l, mid - 1, a);
     51         if (mid < r) build(p -> rs, p ,mid + 1, r, a);
     52         p -> update();
     53     }
     54     #undef mid
     55  
     56      
     57     inline unsigned rand() {
     58         static unsigned res = 826;
     59         return res += res << 2 | 1;
     60     }
     61     inline bool random(int x, int y) {
     62         return rand() % (x + y) < x;
     63     }
     64      
     65     void merge(node *&p, node *x, node *y) {
     66         if (x == null || y == null)
     67             p = x == null ? y : x; else
     68         if (random(x -> sz, y -> sz)) {
     69             p = x;
     70             merge(p -> rs, x -> rs, y);
     71         } else {
     72             p = y;
     73             merge(p -> ls, x, y -> ls);
     74         }
     75         p -> update();
     76     }
     77      
     78     void split(node *p, node *&x, node *&y, int k) {
     79         if (k == 0) {
     80             x = null, y = p;
     81             return;
     82         }
     83         if (k == p -> sz) {
     84             x = p, y = null;
     85             return;
     86         }
     87         if (p -> ls -> sz >= k) {
     88             y = p;
     89             split(p -> ls, x, y -> ls, k);
     90             y -> update();
     91         } else {
     92             x = p;
     93             split(p -> rs, x -> rs, y, k - p -> ls -> sz - 1);
     94             x -> update();
     95         }
     96     }
     97      
     98     inline int get_rank(node *p) {
     99         static int res;
    100         res = p -> ls -> sz + 1;
    101         while (p != T)
    102             res += (p == p -> fa -> rs ? p -> fa -> ls -> sz + 1 : 0), p = p -> fa;
    103         return res;
    104     }
    105      
    106     inline void move(int p, int f) {
    107         static node *x, *y ,*z;
    108         static int t;
    109         t = get_rank(ptr[p]);
    110         split(T, x, z, t), split(x, x, y, t - 1);
    111         if (!f) merge(T, y, x), merge(T, T, z);
    112         else merge(T, x, z), merge(T, T, y);
    113     }
    114      
    115     inline void move_to_mid(int d, int p) {
    116         if (!d) return;
    117         static node *x, *y, *z, *w;
    118         static int t;
    119         t = get_rank(ptr[p]);
    120         split(T, x, z, t), split(x, x, y, t - 1);
    121         if (d == -1) {
    122             split(x, x, w, t - 2);
    123             merge(T, x, y), merge(T, T, w), merge(T, T, z);
    124         } else {
    125             split(z, w, z, 1);
    126             merge(T, x, w), merge(T, T, y), merge(T, T, z);
    127         }
    128     }
    129      
    130     inline int kth(node *p, int k) {
    131         if (k == p -> ls -> sz + 1) return p -> v;
    132         if (k <= p -> ls -> sz) return kth(p -> ls, k);
    133         return kth(p -> rs, k - p -> ls -> sz - 1);
    134     }
    135 };
    136  
    137 int n, m;
    138 int a[N];
    139  
    140 int main() {
    141     using namespace treap;
    142     int i;
    143     char st[10];
    144     n = read(), m = read();
    145     for (i = 1; i <= n; ++i) a[i] = read();
    146     null = new(0, NULL)node, null -> ls = null -> rs = null -> fa = null, null -> sz = 0;
    147     build(T, null, 1, n, a);
    148     for (i = 1; i <= m; ++i) {
    149         scanf("%s", st + 1);
    150         if (st[1] == 'T') move(read(), 0);
    151         if (st[1] == 'B') move(read(), 1);
    152         if (st[1] == 'I') move_to_mid(read(), read());
    153         if (st[1] == 'A') printf("%d
    ", get_rank(ptr[read()]) - 1);
    154         if (st[1] == 'Q') printf("%d
    ", kth(T, read()));
    155     }
    156     return 0;
    157 }
    158  
    159 inline int read() {
    160     static int x, sgn;
    161     static char ch;
    162     x = 0, sgn = 1, ch = getchar();
    163     while (ch < '0' || '9' < ch) {
    164         if (ch == '-') sgn = -1;
    165         ch = getchar();
    166     }
    167     while ('0' <= ch && ch <= '9') {
    168         x = x * 10 + ch - '0';
    169         ch = getchar();
    170     }
    171     return sgn * x;
    172 }
    View Code
  • 相关阅读:
    Oracle 删除表中的一整列
    如何查看数据库中表的创建时间
    Oracle数据库的简单数据恢复
    分治和动态规划
    深入浅出 妙用Javascript中apply、call、bind
    CSS3 Background-size
    WampServer 2.5设置外网访问/局域网手机访问(403 Forbidden错误解决方法)
    js中apply方法的使用
    Leetcode No.1 Two Sum
    Python的sys.argv使用说明
  • 原文地址:https://www.cnblogs.com/rausen/p/4480431.html
Copyright © 2011-2022 走看看