码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2658: [Zjoi2012]小蓝的好友(mrx)

时间:2016-02-26 20:40:13      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:

太神辣 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 }
View Code

 

bzoj2658: [Zjoi2012]小蓝的好友(mrx)

标签:

原文地址:http://www.cnblogs.com/showson/p/5221581.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!