题目是中文描述,题意也就不赘述了
实际上我们是动态维护两个集合,对于一个集合,当进入一个新的数的时候,在另一个集合的已有的数中找一个和它最接近的,然后把这个两数取出来,计算绝对值。
数据已经保证每一个集合里面的每一个数都是不一样的,那么这道题就简单了,我们只需要维护两棵平衡树,我选择的是喜闻乐见的Treap……
那么某一个集合进入一个新数的时候,我们只需要询问另外一个集合是否为空,假设不为空,我们就询问一下它的前驱以及后继,找到那个最接近的就行……
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
using namespace std;
const int N = 80010;
const int inf = ~0u >> 1;
const int mod = 1000000;
struct Treap{
struct node{
node *ch[2];
int v, p, sz;
node(int _v, node *n):
v(_v){ch[0] = ch[1] = n; p = rand(); sz = 1;}
void update(){sz = ch[0]->sz + 1 + ch[1]->sz;}
};
node *root, *null;
Treap(){
}
void init(){
null = new node(0, 0); null->sz = 0; null->p = inf;
null->ch[0] = null->ch[1] = null;
root = null;
}
void rotate(node *&t, bool d){
node *_t = t->ch[d];
t->ch[d] = _t->ch[!d];
_t->ch[!d] = t;
_t->update();
t->update();
t = _t;
}
void __insert(node *&t, int val){
if (t == null){
t = new node(val, null);
return;
}
bool d = val > t->v;
__insert(t->ch[d], val);
if (t->ch[d]->p < t->p) rotate(t, d);
t->update();
}
void __del(node *&t, int val){
if (t == null) return;
if (val == t->v){
bool d = t->ch[1]->p < t->ch[0]->p;
if (t->ch[d] == null){
delete t; t = null; return;
}
rotate(t, d);
__del(t->ch[!d], val);
}else{
bool d = val > t->v;
__del(t->ch[d], val);
}
t->update();
}
void __show(node *t){
if (t == null) return;
__show(t->ch[0]);
printf("%d ", t->v);
__show(t->ch[1]);
}
void insert(int val){
__insert(root, val);
}
void del(int val){
__del(root, val);
}
node *pred(node *t, int val, node *ans){
if (t == null) return ans;
if (t->v <= val)
return pred(t->ch[1], val, t);
else
return pred(t->ch[0], val, ans);
}
node *succ(node *t, int val, node *ans){
if (t == null) return ans;
if (t->v >= val)
return succ(t->ch[0], val, t);
else
return succ(t->ch[1], val, ans);
}
void show(){
__show(root);
puts("");
}
void __fre(node *t){
if (t == null) return;
__fre(t->ch[0]);
__fre(t->ch[1]);
delete t;
}
void fre(){
__fre(root);
}
int size(){
return root->sz;
}
int solve(int val){
node *pre, *suc;
pre = pred(root, val, null);
suc = succ(root, val, null);
if (pre != null && suc != null){
if (abs(val - (pre->v)) > abs(val - (suc->v))){
del(suc->v);
return abs(val - (suc->v));
}else{
del(pre->v);
return abs(val - (pre->v));
}
}else if (pre == null){
del(suc->v);
return abs(val - (suc->v));
}else if (suc == null){
del(pre->v);
return abs(val - (pre->v));
}
}
};
int n, op, a;
Treap x, y;
int main(){
scanf("%d", &n);
x.init(); y.init();
int ans = 0;
for (int i = 1; i <= n; i++){
scanf("%d%d", &op, &a);
if (op == 0){
if (y.size() == 0)
x.insert(a);
else
ans = (ans + y.solve(a)) % mod;
}else{
if (x.size() == 0)
y.insert(a);
else
ans = (ans + x.solve(a)) % mod;
}
}
printf("%d\n", ans % mod);
return 0;
}