用Splaytree实现插入一个节点,删除一个节点,求第k大的数,求小于某值的个数,还是挺好玩的,注意这题答案要mod一下。
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 80000 + 10;
const int mod = 1000000;
const int inf = 2e9;
#define lson x->ch[0]
#define rson x->ch[1]
#define ket (root->ch[1]->ch[0])
struct NODE {
NODE *pre, *ch[2];
int val, id, sz;
void up() {
sz = ch[0]->sz + ch[1]->sz + 1;
}
};
struct Splaytree {
NODE node[maxn], *null, *root;
int top;
void Rotate(NODE *x, int c) {
NODE *y = x->pre;
y->ch[!c] = x->ch[c];
if(x->ch[c] != null) x->ch[c]->pre = y;
x->pre = y->pre;
if(y->pre != null) y->pre->ch[ y->pre->ch[1]==y ] = x;
x->ch[c] = y; y->pre = x;
y->up();
}
void Splay(NODE *x, NODE *go) {
while(x->pre != go) {
if(x->pre->pre == go) Rotate(x, x->pre->ch[0] == x);
else {
NODE *y = x->pre, *z = y->pre;
int f = z->ch[1] == y;
if(y->ch[f] == x) Rotate(y, !f);
else Rotate(x, f);
Rotate(x, !f);
}
}
x->up();
if(go == null) root = x;
}
void RTO(int k, NODE *go) {
NODE *x = root;
while(lson->sz != k) {
if(lson->sz > k) x = lson;
else {
k -= lson->sz + 1;
x = rson;
}
}
Splay(x, go);
}
void debug(NODE *x) {
if(x != null) {
printf("节点: %2d 左儿子: %2d 右儿子: %2d size = %2d val = %2d\n",
x->id, x->ch[0]->id, x->ch[1]->id, x->sz, x->val);
debug(x->ch[0]);
debug(x->ch[1]);
}
}
int find_kth(NODE*x, int k) {
if(lson->sz == k) return x->val;
if(lson->sz > k) return find_kth(lson, k);
return find_kth(rson, k - lson->sz - 1);
}
int find_sm(NODE* x, int c) {
if(x == null) return 0;
if(x->val <= c) return lson->sz + 1 + find_sm(rson, c);
else return find_sm(lson, c);
}
void Delete(int l, int r) {
RTO(l-1, null);
RTO(r+1, root);
ket = null;
root->ch[1]->up(); root->up();
}
void Insert(int c) {
NODE *x = root;
if(x == null) {
x = newnode(c, null);
root = x;
return ;
}
while(x->ch[x->val < c] != null)
x = x->ch[x->val < c];
x->ch[x->val < c] = newnode(c, x);
Splay(x->ch[x->val < c], null);
}
NODE* newnode(int c, NODE *f) {
NODE *x = &node[++top];
x->val = c; x->sz = 1; x->id = top;
lson = rson = null;
x->pre = f;
return x;
}
void init() {
null = &node[0];
null->sz = null->id = null->val = 0;
top = 0;
root = null;
Insert(-inf); Insert(inf);
}
int gao(int b) {
int cnt = find_sm(root, b);
int c1 = find_kth(root, cnt-1), c2 = find_kth(root, cnt);
if((ll)b - c1 <= (ll)c2 - b){
Delete(cnt-1, cnt-1);
return b-c1;
}
else {
Delete(cnt, cnt);
return c2-b;
}
}
}*Q, *L;
void solve() {
Q = new Splaytree; L = new Splaytree;
Q->init(); L->init();
int n, a, b;
scanf("%d", &n);
int ans = 0;
while(n--) {
scanf("%d%d", &a, &b);
if(!a) {
if(L->root->sz > 2)
ans += L->gao(b);
else
Q->Insert(b);
}
else {
if(Q->root->sz > 2)
ans += Q->gao(b);
else
L->Insert(b);
}
ans %= mod;
}
printf("%d\n", ans);
}
int main() {
solve();
return 0;
}