BZOJ 1208: [HNOI2004]宠物收养所
1208: [HNOI2004]宠物收养所
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 7483 Solved: 2968
[Submit][Status][Discuss]
Description
最近,阿Q开了一间宠物收养所。收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物。每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值。这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少。 1. 被遗弃的宠物过多时,假若到来一个领养者,这个领养者希望领养的宠物的特点值为a,那么它将会领养一只目前未被领养的宠物中特点值最接近a的一只宠物。(任何两只宠物的特点值都不可能是相同的,任何两个领养者的希望领养宠物的特点值也不可能是一样的)如果有两只满足要求的宠物,即存在两只宠物他们的特点值分别为a-b和a+b,那么领养者将会领养特点值为a-b的那只宠物。 2. 收养宠物的人过多,假若到来一只被收养的宠物,那么哪个领养者能够领养它呢?能够领养它的领养者,是那个希望被领养宠物的特点值最接近该宠物特点值的领养者,如果该宠物的特点值为a,存在两个领养者他们希望领养宠物的特点值分别为a-b和a+b,那么特点值为a-b的那个领养者将成功领养该宠物。 一个领养者领养了一个特点值为a的宠物,而它本身希望领养的宠物的特点值为b,那么这个领养者的不满意程度为abs(a-b)。【任务描述】你得到了一年当中,领养者和被收养宠物到来收养所的情况,希望你计算所有收养了宠物的领养者的不满意程度的总和。这一年初始时,收养所里面既没有宠物,也没有领养者。
Input
第一行为一个正整数n,n<=80000,表示一年当中来到收养所的宠物和领养者的总数。接下来的n行,按到来时间的先后顺序描述了一年当中来到收养所的宠物和领养者的情况。每行有两个正整数a, b,其中a=0表示宠物,a=1表示领养者,b表示宠物的特点值或是领养者希望领养宠物的特点值。(同一时间呆在收养所中的,要么全是宠物,要么全是领养者,这些宠物和领养者的个数不会超过10000个)
Output
仅有一个正整数,表示一年当中所有收养了宠物的领养者的不满意程度的总和mod 1000000以后的结果。
Sample Input
0 2
0 4
1 3
1 2
1 5
Sample Output
(abs(3-2) + abs(2-4)=3,最后一个领养者没有宠物可以领养)
HINT
Source
模拟以下宠物收养所里的各类生物(人或宠物)的存在情况即可,每次来一个不同的生物(不同于收养所中已有的生物)时,找到差值最小那个和其配对即可。大神请自觉Splay,蒟蒻如我请STL set水过。
1 const int mod = 1000000; 2 const int inf = 2e9 + 7; 3 4 int answer; 5 int waiting; 6 std::set<int> S; 7 8 inline int solve(int v) { 9 std::set<int>::iterator 10 nxt = S.lower_bound(v), prv = nxt; 11 if (abs(*--prv - v) <= abs(*nxt - v)) 12 return S.erase(prv), abs(*prv - v); 13 return S.erase(nxt), abs(*nxt - v); 14 } 15 16 signed main(void) { 17 S.insert(inf), S.insert(-inf); 18 for (int n = next(); n--; ) { 19 int k = next(), v = next(); 20 if (waiting == k || S.size() <= 2) 21 waiting = k, S.insert(v); 22 else (answer += solve(v)) %= mod; 23 } 24 printf("%d\n", answer); 25 }
12月8日,初识Splay。
1 #include <bits/stdc++.h> 2 3 const int mod = 1000000; 4 const int inf = 2e9 + 9; 5 6 class Splay { 7 public: 8 Splay(void) { 9 root = NULL; 10 } 11 12 inline bool empty(void) { 13 return root == NULL; 14 } 15 16 inline void insert(int val) { 17 if (root == NULL) 18 root = new node(val, NULL); 19 for (node *t = root; t; t = t->son[val >= t->value]) { 20 if (t->value == val) { spaly(t, NULL); return; } 21 if (t->son[val >= t->value] == NULL) 22 t->son[val >= t->value] = new node(val, t); 23 } 24 } 25 26 inline void erase(int val) { 27 node *t = root; 28 for ( ; t; ) { 29 if (t->value == val) 30 break; 31 t = t->son[val > t->value]; 32 } 33 if (t != NULL) { 34 spaly(t, NULL); 35 if (t->son[0] == NULL) { 36 root = t->son[1]; 37 if (root != NULL) 38 root->father = NULL; 39 } 40 else { 41 node *p = t->son[0]; 42 while (p->son[1] != NULL) 43 p = p->son[1]; 44 spaly(p, t); root = p; 45 root->father = NULL; 46 p->son[1] = t->son[1]; 47 if (p->son[1] != NULL) 48 p->son[1]->father = p; 49 } 50 } 51 } 52 53 inline int prv(int val) { 54 int ret = -inf; 55 for (node *t = root; t; ) { 56 if (t->value == val) 57 return val; 58 if (t->value < val) 59 if (ret < t->value) 60 ret = t->value; 61 t = t->son[val > t->value]; 62 } 63 return ret; 64 } 65 66 inline int nxt(int val) { 67 int ret = inf; 68 for (node *t = root; t; ) { 69 if (t->value == val) 70 return val; 71 if (t->value > val) 72 if (ret > t->value) 73 ret = t->value; 74 t = t->son[val > t->value]; 75 } 76 return ret; 77 } 78 79 private: 80 struct node { 81 int value; 82 node *father; 83 node *son[2]; 84 85 node(int v = 0, node *f = NULL) { 86 value = v; 87 father = f; 88 son[0] = NULL; 89 son[1] = NULL; 90 } 91 }*root; 92 93 inline bool son(node *f, node *s) { 94 return f->son[1] == s; 95 } 96 97 inline void rotate(node *t) { 98 node *f = t->father; 99 node *g = f->father; 100 bool a = son(f, t), b = !a; 101 f->son[a] = t->son[b]; 102 if (t->son[b] != NULL) 103 t->son[b]->father = f; 104 t->son[b] = f; 105 f->father = t; 106 t->father = g; 107 if (g != NULL) 108 g->son[son(g, f)] = t; 109 else 110 root = t; 111 } 112 113 inline void spaly(node *t, node *p) { 114 while (t->father != p) { 115 node *f = t->father; 116 node *g = f->father; 117 if (g == p) 118 rotate(t); 119 else { 120 if (son(g, f) ^ son(f, t)) 121 rotate(t), rotate(t); 122 else 123 rotate(f), rotate(t); 124 } 125 } 126 } 127 }S; 128 129 inline int solve(int v) { 130 int a = S.prv(v); 131 int b = S.nxt(v); 132 if (v - a <= b - v) 133 return S.erase(a), v - a; 134 else 135 return S.erase(b), b - v; 136 } 137 138 int answer, waiting; 139 140 signed main(void) { 141 int n; scanf("%d", &n); 142 for (int i = 1; i <= n; ++i) { 143 int k, v; scanf("%d%d", &k, &v); 144 if (S.empty() || waiting == k) 145 S.insert(v), waiting = k; 146 else 147 (answer += solve(v)) %= mod; 148 } 149 printf("%d\n", answer); 150 }
@Author: YouSiki