题目
简化题意
有一堆人和一堆宠物,来的有先后顺序,每个人想要一只 特点值为 (a) 的宠物,我们会从现有的猫中调一只和这个 (a) 差的最小的,如果有差相同的就选特点值小的。
如果人多出了,来了一只猫找的也是差最小的人。
计算每次配对的宠物的特点值和人想要的特点值得差的绝对值的和。
思路
Splay。
简单的维护前驱后继的问题。Splay维护一下。
至此,今天的第一课 Splay 终于写完了,早自习码完代码,找 bug 找了一上午。。。
Code
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define MAXN 100001
inline void read(int &T) {
int x = 0;
bool f = 0;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') f = !f;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
T = f ? -x : x;
}
const int mod = 1000000;
int n, root, ans, fa[MAXN], son[MAXN][2];
int num, size[MAXN], cnt[MAXN], val[MAXN];
int which(int x) { return son[fa[x]][1] == x ? 1 : 0; }
void update(int x) { size[x] = cnt[x] + size[son[x][0]] + size[son[x][1]]; }
void clear(int x) { fa[x] = son[x][0] = son[x][1] = cnt[x] = size[x] = val[x] = 0; }
void rotate(int x) {
int father = fa[x], grandpa = fa[father];
int flag1 = which(x), flag2 = which(father);
fa[x] = grandpa, fa[father] = x;
if (grandpa) son[grandpa][flag2] = x;
fa[son[x][flag1 ^ 1]] = father;
son[father][flag1] = son[x][flag1 ^ 1];
son[x][flag1 ^ 1] = father;
update(x), update(father);
}
void splay(int x) {
for (int f = fa[x]; f = fa[x], f; rotate(x)) {
if (fa[f]) rotate(which(x) == which(f) ? f : x);
}
root = x;
}
int pre() {
int now = son[root][0];
while (son[now][1]) now = son[now][1];
splay(now); return now;
}
int nxt() {
int now = son[root][1];
while (son[now][0]) now = son[now][0];
splay(now); return now;
}
int qrank(int x) {
int ans = 0, now = root;
while (1) {
if (val[now] > x) now = son[now][0];
else {
ans += size[son[now][0]];
if (val[now] == x) {
splay(now);
return ans + 1;
}
ans += cnt[now];
now = son[now][1];
}
}
}
void ins(int x) {
if (!root) {
val[++num] = x;
++cnt[num];
root = num;
update(num);
return;
}
int now = root, f = 0;
while (1) {
if (val[now] == x) {
++cnt[now];
update(now), update(f);
splay(now);
return;
}
f = now, now = son[now][val[now] < x];
if (!now) {
val[++num] = x, ++cnt[num];
fa[num] = f, son[f][val[f] < x] = num;
update(num), update(f), splay(num);
return;
}
}
}
void del(int x) {
qrank(x);
if (cnt[root] > 1) {
--cnt[root];
update(root);
return;
}
if (!son[root][0] && !son[root][1]) {
clear(root);
root = 0;
return;
}
if (!son[root][0]) {
int now = root;
root = son[root][1];
fa[root] = 0;
clear(now);
return;
}
if (!son[root][1]) {
int now = root;
root = son[root][0];
fa[root] = 0;
clear(now);
return;
}
int now = root, k = pre();
son[k][1] = son[now][1];
fa[son[now][1]] = k;
clear(now), update(root);
}
int main() {
read(n);
int typ_, tot = 0;
for (int i = 1, typ, x; i <= n; ++i) {
read(typ), read(x);
if (!tot) {
typ_ = typ;
ins(x);
++tot;
}
else {
if (typ_ == typ) ++tot, ins(x);
else {
--tot;
ins(x);
if (cnt[root] > 1) del(x);
else {
int minn = 2147483647, maxx = 2147483647;
int rt = root;
if (son[root][0]) minn = val[pre()];
splay(rt);
if (son[root][1]) maxx = val[nxt()];
splay(rt);
if (son[root][0] && son[root][1]) {
if (abs(x - minn) <= abs(maxx - x)) {
ans = (1ll * ans + 1ll * x - 1ll * minn) % mod;
del(minn);
}
else {
ans = (1ll * ans + 1ll * maxx - 1ll * x) % mod;
del(maxx);
}
}
else {
if (son[root][0]) {
ans = (1ll * ans + 1ll * x - 1ll * minn) % mod;
del(minn);
}
else if (son[root][1]) {
ans = (1ll * ans + 1ll * maxx - 1ll * x) % mod;
del(maxx);
}
}
}
del(x);
}
}
}
std::cout << ans << '
';
return 0;
}