bzoj2658: [Zjoi2012]小蓝的好友(mrx)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于bzoj2658: [Zjoi2012]小蓝的好友(mrx)的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ2656[Zjoi2012]数列(sequence) 高精度