序列是有序的,我们只要找到查找小于x的最大值与大于x的最小值即可,然后计算sum。看了老大博客,说了要注意取模时候的方式,sum = (sum+xx)%1000000,所以在此处没有走弯路,但是在输入的部分,确实栽了一个大跟头,开始没考虑两种情况的不同,以为处理方式是一样的,4wa后,才注意到是不同的。之后一直在纠结怎么插入了。后来加了一个变量才解决的问题。
/*************************************************************************
> File Name: hysbz1208.cpp
> Author: Ac_Toy
> Mail: ycsgldy@163.com
> Created Time: 2013年06月21日 星期五 06时48分17秒
************************************************************************/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef unsigned int u32;
typedef long long i64;
typedef unsigned long long u64;
typedef vector<int> IV;
typedef vector<bool> BV;
typedef pair<int,int> II;
typedef vector<II> IIV;
#define For(t,v,c) for(t::const_iterator v=c.begin(); v!=c.end(); ++v)
const int INF = 0x7FFFFFFF;
const double eps = 1E-10;
const double PI = acos(-1);
struct Node *null;
int cnt;//序列元素个数
struct Node {
Node *ch[2];
int s;//结点总数
int flip;
i64 v;
i64 lazy;
int cmp(int k) const {
int d = k - ch[0]->s;
if ( d == 1 ) return -1;
return d <= 0 ? 0 : 1;
}
void maintain() {
s = ch[0]->s + ch[1]->s + 1;
}
void pushdown() {
if(flip) {
flip = 0;
swap(ch[0], ch[1]);
ch[0]->flip ^= 1; ch[1]->flip ^= 1;//ch[0]->flip = !ch[0]->flip;ch[1]->flip = !ch[1]->flip;
}
if(lazy) {
ch[0]->v += lazy;
ch[0]->lazy += lazy;
ch[1]->v += lazy;
ch[1]->lazy += lazy;
}
lazy = 0;
}
};
void rotate(Node* &o, int d) {//旋转
Node* k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o;
o->maintain(); k->maintain(); o = k;
}
void splay(Node* &o, int k) {//找到序列的左数第k个元素并伸展到根
o->pushdown();
int d = o->cmp(k);
if(d == 1) k -= o->ch[0]->s + 1;
if(d != -1) {
Node* p = o->ch[d];
p->pushdown();
int d2 = p->cmp(k);
int k2 = (d2 == 0 ? k : k - p->ch[0]->s - 1);
if(d2 != -1) {
splay(p->ch[d2], k2);
if(d == d2) rotate(o, d^1); else rotate(o->ch[d], d);
}
rotate(o, d^1);
}
}
// 合并left和right。假定left的所有元素比right小。注意right可以是null,但left不可以
Node* merge(Node* left, Node* right) {
splay(left, left->s);
left->ch[1] = right;
left->maintain();
return left;
}
// 把o的前k小结点放在left里,其他的放在right里。1<=k<=o->s。当k=o->s时,right=null
void split(Node* o, int k, Node* &left, Node* &right) {
splay(o, k);
left = o;
right = o->ch[1];
o->ch[1] = null;
left->maintain();
}
const int maxn = 80000 + 10;
int A[maxn];
struct SplaySequence {
int n;
Node seq[maxn];
Node *root;
Node* build(int sz) {
if(!sz) return null;
Node* L = build(sz/2);
Node* o = &seq[++n];
o->v = A[n-1];//结点编号;A[0]是虚拟结点
o->ch[0] = L;
o->ch[1] = build(sz - sz/2 - 1);
o->flip = o->s = o->lazy = 0;
o->maintain();
return o;
}
void init(int sz) {
n = 0;
null = new Node();
null->s = null->v = null->flip = null->lazy = 0;
root = build(sz);
}
};
vector<int> ans;
void print(Node* o) {
if(o != null) {
o->pushdown();
print(o->ch[0]);
ans.push_back(o->v);
print(o->ch[1]);
}
}
void debug(Node* o) {
if(o != null) {
o->pushdown();
debug(o->ch[0]);
printf ( "%lld ", o->v );
//printf ( " v=%d,s=%d,flip=%d,lazy=%d,mi=%d", o->v,o->s,o->flip,o->lazy2,o->mi);
//printf ( "%d, left=%d,s=%d,mi=%d,*right=%d,s=%d,mi=%d\n", o->v, o->ch[0]->v,o->ch[0]->s,o->ch[0]->mi, o->ch[1]->v,o->ch[1]->s,o->ch[1]->mi );
debug(o->ch[1]);
}
}
SplaySequence ss;
void add(int x) {
cnt++;
Node *p = ss.root;
//puts("p");debug(p);puts("");
int k = 0;
while(p != null) {
p->pushdown();
if(p->v > x) p = p->ch[0];
else {
k += p->ch[0]->s + 1;
p = p->ch[1];
}
}
Node *left, *mid, *right;
split(ss.root, k, left, right);
mid = new Node();
mid->ch[0] = mid->ch[1] = null;
mid->v = x;
mid->s = 1;
mid->lazy = 0;
ss.root = merge(merge(left, mid), right);
//puts("add");debug(ss.root);puts("");
}
void del(int x) {
int k = 0;
Node *p = ss.root;
while(p != null) {
if(p->v >= x) p = p->ch[0];
else {
k += p->ch[0]->s + 1;
p = p->ch[1];
}
}
Node *left, *right, *o, *mid;
split(ss.root, k, left, o);
split(o, 1, mid, right);
ss.root = merge(left, right);
cnt--;
}
int find_low(int x) {
Node *p = ss.root, *ret = null;
while(p != null) {
if(p->v <= x) ret = p, p = p->ch[1];
else p = p->ch[0];
}
return ret->v;
}
int find_up(int x) {
Node *p = ss.root, *ret = null;
while(p != null) {
if(p->v >= x) ret = p, p = p->ch[0];
else p = p->ch[1];
}
return ret->v;
}
int main()
{
bool flag;
int Case;
i64 sum, x, y;
sum = 0;
scanf("%d", &Case);
A[0] = -INF;
ss.init(1);
//puts("start");debug(ss.root);puts("");
while(Case--) {
scanf("%lld%lld", &x, &y);
if(x == 0) {
if(!flag || cnt < 1) {
add(y);
flag = 0;
}
else {
int tmp1 = find_low(y), tmp2 = find_up(y), xx;
//printf ("tmp1 = %d tmp2 = %d\n", tmp1, tmp2);
if(abs(tmp1 - y) == abs(tmp2 - y)) del(tmp1), xx = abs(tmp1 - y);
else if(abs(tmp1 - y) < abs(tmp2 - y)) del(tmp1), xx = abs(tmp1 - y);
else if(abs(tmp1 - y) > abs(tmp2 - y)) del(tmp2), xx = abs(tmp2 - y);
//int xx = min(abs(tmp1 - y), abs(tmp2 - y));
//printf("xx = %d\n", xx);
sum = (sum + xx) % 1000000;
}
}
else if(x == 1) {
if(flag || cnt < 1) {
flag = 1;
add(y);
}
else {
int tmp1 = find_low(y), tmp2 = find_up(y), xx;
//printf ("tmp1 = %d tmp2 = %d\n", tmp1, tmp2);
if(abs(tmp1 - y) == abs(tmp2 - y)) del(tmp1), xx = abs(tmp1 - y);
else if(abs(tmp1 - y) < abs(tmp2 - y)) del(tmp1), xx = abs(tmp1 - y);
else if(abs(tmp1 - y) > abs(tmp2 - y)) del(tmp2), xx = abs(tmp2 - y);
//int xx = min(abs(tmp1 - y), abs(tmp2 - y));
//printf("xx = %d\n", xx);
sum = (sum + xx) % 1000000;
}
}
/*if(x == 0) {
add(y);
}
else if(x == 1) {
if ( cnt < 1 ) add(y);
int tmp1 = find_low(y), tmp2 = find_up(y), xx;
//printf ("tmp1 = %d tmp2 = %d\n", tmp1, tmp2);
if(abs(tmp1 - y) == abs(tmp2 - y)) del(tmp1), xx = abs(tmp1 - y);
else if(abs(tmp1 - y) < abs(tmp2 - y)) del(tmp1), xx = abs(tmp1 - y);
else if(abs(tmp1 - y) > abs(tmp2 - y)) del(tmp2), xx = abs(tmp2 - y);
//int xx = min(abs(tmp1 - y), abs(tmp2 - y));
//printf("xx = %d\n", xx);
sum = (sum + xx) % 1000000;
}*/
}
printf("%lld\n", sum);
return 0;
}