zoukankan      html  css  js  c++  java
  • bzoj2658: [Zjoi2012]小蓝的好友(mrx)

    太神辣 treap的随机键值竟然能派上用场。。

    要用不旋转的treap来进行维护区间信息

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<algorithm>
      5 #include<iostream>
      6 
      7 using namespace std;
      8 
      9 template<typename Q> Q &read(Q &x) {
     10     static char c, f;
     11     for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1;
     12     for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0';
     13     if(f) x = -x; return x;
     14 }
     15 template<typename Q> Q read() {
     16     static Q x; read(x); return x;
     17 }
     18 
     19 typedef long long LL;
     20 const int N = 40000 + 10;
     21 
     22 LL S(LL x) {
     23     return x * (x + 1) >> 1;
     24 }
     25 
     26 struct Node *null, *pis;
     27 struct Node {
     28     int sz, h, tag;
     29     LL ans;
     30     Node *ch[2];
     31     
     32     Node() {}
     33     Node(int h) : h(h) {
     34         sz = 1, ans = tag = 0;
     35         ch[0] = ch[1] = null;
     36     }
     37     
     38     void add(int d) {
     39         if(this == null) return;
     40         h += d, tag += d;
     41     }
     42     
     43     void maintain() {
     44         sz = ch[0]->sz + ch[1]->sz + 1;
     45         ans = 0;
     46         for(int c = 0; c < 2; c++) {
     47             ans += ch[c]->ans + S(ch[c]->sz) * (ch[c]->h - h);
     48         }
     49     }
     50     
     51     void down() {
     52         ch[0]->add(tag);
     53         ch[1]->add(tag);
     54         tag = 0;
     55     }
     56     
     57     void *operator new(size_t) {
     58         return pis++;
     59     }
     60 }pool[N];
     61 
     62 Node *merge(Node *l, Node *r) {
     63     if(l == null) return r;
     64     if(r == null) return l;
     65     if(l->h < r->h) {
     66         l->down();
     67         l->ch[1] = merge(l->ch[1], r);
     68         return l->maintain(), l;
     69     }else {
     70         r->down();
     71         r->ch[0] = merge(l, r->ch[0]);
     72         return r->maintain(), r;
     73     }
     74 }
     75 
     76 typedef pair<Node *, Node *> pnn;
     77 pnn split(Node *o, int k) {
     78     if(o == null) return pnn(null, null);
     79     pnn res; o->down();
     80     if(o->ch[0]->sz >= k) {
     81         res = split(o->ch[0], k);
     82         o->ch[0] = res.second;
     83         res.second = o;
     84     }else {
     85         res = split(o->ch[1], k - o->ch[0]->sz - 1);
     86         o->ch[1] = res.first;
     87         res.first = o;
     88     }
     89     return o->maintain(), res;
     90 }
     91 
     92 pair<int, int> p[100000 + 10];
     93 
     94 int main() {
     95 #ifdef DEBUG
     96     freopen("in.txt", "r", stdin);
     97     freopen("out.txt", "w", stdout);
     98 #endif
     99     
    100     int r, c, n;
    101     scanf("%d%d%d", &r, &c, &n);
    102     for(int i = 0; i < n; i++) {
    103         scanf("%d%d", &p[i].first, &p[i].second);
    104     }
    105     sort(p, p + n);
    106     
    107     pis = pool, null = new Node(0);
    108     null->sz = 0;
    109     Node *root = null;
    110     for(int i = 1; i <= c; i++) {
    111         root = merge(root, new Node(0));
    112     }
    113     
    114     LL ans = S(r) * S(c);
    115     for(int i = 1, j = 0; i <= r; i++) {
    116         root->add(1);
    117         while(j < n && p[j].first == i) {
    118             int x = p[j++].second;
    119             pnn r1 = split(root, x - 1);
    120             pnn r2 = split(r1.second, 1);
    121             r2.first->h = 0;
    122             root = merge(merge(r1.first, r2.first), r2.second);
    123         }
    124         ans -= root->ans + S(root->sz) * root->h;
    125     }
    126     cout << ans << endl;
    127     
    128     return 0;
    129 }
    fhq treap

    谁说一定要用fhq treap?

    用普通的treap就好了 而且常数小!

    注意建树最好$O(n)$建一下,每次insert有可能退化成$O(n^2)$的。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<algorithm>
      5 #include<iostream>
      6  
      7 using namespace std;
      8  
      9 template<typename Q> Q &read(Q &x) {
     10     static char c, f;
     11     for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1;
     12     for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0';
     13     if(f) x = -x; return x;
     14 }
     15 template<typename Q> Q read() {
     16     static Q x; read(x); return x;
     17 }
     18  
     19 typedef long long LL;
     20 const int N = 40000 + 10;
     21  
     22 LL S(LL x) {
     23     return x * (x + 1) >> 1;
     24 }
     25  
     26 struct Node *null, *pis, *bin[N];
     27 int top;
     28 struct Node {
     29     int sz, v, h, tag;
     30     LL ans;
     31     Node *ch[2];
     32      
     33     Node() {}
     34     Node(int v, int h) : v(v), h(h) {
     35         sz = 1, ans = tag = 0;
     36         ch[0] = ch[1] = null;
     37     }
     38      
     39     void add(int d) {
     40         if(this == null) return;
     41         h += d, tag += d;
     42     }
     43      
     44     void maintain() {
     45         sz = ch[0]->sz + ch[1]->sz + 1;
     46         ans = 0;
     47         for(int c = 0; c < 2; c++) {
     48             ans += ch[c]->ans + S(ch[c]->sz) * (ch[c]->h - h);
     49         }
     50     }
     51      
     52     void down() {
     53         ch[0]->add(tag);
     54         ch[1]->add(tag);
     55         tag = 0;
     56     }
     57      
     58     void *operator new(size_t) {
     59         return top ? bin[--top] : pis++;
     60     }
     61     
     62     void operator delete(void *p) {
     63         bin[top++] = (Node *) p;
     64     }
     65     
     66     int cmp(int x) const {
     67         if(x == v) return -1;
     68         return x < v ? 0 : 1;
     69     }
     70 }pool[N];
     71 
     72 void rotate(Node *&o, int d) {
     73     Node *t = o->ch[d];
     74     o->ch[d] = t->ch[d ^ 1];
     75     t->ch[d ^ 1] = o;
     76     o->maintain();
     77     (o = t)->maintain();
     78 }
     79 
     80 void modify(Node *&o, int x, int w) {
     81     o->down();
     82     int d = o->cmp(x);
     83     if(d == -1) return o->h = w, o->maintain(), void();
     84     modify(o->ch[d], x, w);
     85     if(o->ch[d]->h < o->h) rotate(o, d);
     86     else o->maintain();
     87 }
     88 
     89 pair<int, int> p[100000 + 10];
     90 
     91 void build(Node *&o, int l, int r) {
     92     if(l > r) return;
     93     int mid = (l + r) >> 1;
     94     o = new Node(mid, 0);
     95     build(o->ch[0], l, mid - 1);
     96     build(o->ch[1], mid + 1, r);
     97     o->maintain();
     98 }
     99 
    100 int main() {
    101 #ifdef DEBUG
    102     freopen("in.txt", "r", stdin);
    103     freopen("out.txt", "w", stdout);
    104 #endif
    105      
    106     int r, c, n;
    107     scanf("%d%d%d", &r, &c, &n);
    108     for(int i = 0; i < n; i++) {
    109         read(p[i].first), read(p[i].second);
    110     }
    111     sort(p, p + n);
    112      
    113     pis = pool, null = new Node(0, 0);
    114     null->sz = 0;
    115     Node *root;
    116     build(root, 1, c);
    117     
    118     LL ans = S(r) * S(c);
    119     for(int i = 1, j = 0; i <= r; i++) {
    120         root->add(1);
    121         while(j < n && p[j].first == i) {
    122             modify(root, p[j++].second, 0);
    123         }
    124         ans -= root->ans + S(root->sz) * root->h;
    125     }
    126     cout << ans << endl;
    127      
    128     return 0;
    129 }
    普通treap
  • 相关阅读:
    MOS
    1- Bluetooth开发
    1- Bluetooth
    MCU 51-10 Infrared Communication
    1- STM32 HAL库学习 GPIO配置点亮LED灯
    MCU 51-9 DS18B20 Temperature Sensor
    MCU 51-8 AD/DA
    C语言讲义——变量(variable)
    C语言讲义——注释
    C语言讲义——“编译、链接”
  • 原文地址:https://www.cnblogs.com/showson/p/5221581.html
Copyright © 2011-2022 走看看