[BZOJ2716][Violet 3]天使玩偶
[BZOJ2716][Violet 3]天使玩偶
试题描述
.gif)
输入
.gif)
输出
.gif)
输入示例
第一个测试点,我就不拿来占页面了= =
输出示例
同上
数据规模及约定
= =题目中给的范围不对。。。交上去RE。。。我目测大概 N, M ≤ 600000,xi, yi ≤ 107.
题解
出题人cnbb!
1.) 数据超大,时限 80 sec,出题人恶意卡测评机!
2.) 不能用任何读入优化。
3.) 数据范围还给错了!
4.) kd树模板删边题。【正经的题解只有这一句
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;
const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
#define maxn 1200010
#define oo 40000000
int n, m;
int root, lc[maxn], rc[maxn];
bool Cur;
struct Node {
int x[2], mx[2], mn[2];
bool operator < (const Node& t) const { return x[Cur] != t.x[Cur] ? x[Cur] < t.x[Cur] : x[Cur^1] < t.x[Cur^1]; }
int operator * (const Node& t) const { return abs(x[0] - t.x[0]) + abs(x[1] - t.x[1]); }
} ns[maxn];
void maintain(int o) {
int l = lc[o], r = rc[o];
for(int i = 0; i < 2; i++) {
ns[o].mx[i] = max(max(ns[l].mx[i], ns[r].mx[i]), ns[o].x[i]);
ns[o].mn[i] = min(min(ns[l].mn[i], ns[r].mn[i]), ns[o].x[i]);
}
return ;
}
void build(int& o, int L, int R, bool cur) {
if(L > R){ o = 0; return ; }
int M = L + R >> 1; o = M;
Cur = cur; nth_element(ns + L, ns + M, ns + R + 1);
build(lc[o], L, M - 1, cur ^ 1); build(rc[o], M + 1, R, cur ^ 1);
return maintain(o);
}
Node x;
void Ins(int& o, bool cur) {
if(!o) ns[o = ++n] = x;
else {
if(ns[o].x[cur] < x.x[cur]) Ins(rc[o], cur ^ 1);
else Ins(lc[o], cur ^ 1);
}
return maintain(o);
}
int calc(int b) {
int sum = 0;
for(int i = 0; i < 2; i++) {
if(x.x[i] < ns[b].mn[i]) sum += ns[b].mn[i] - x.x[i];
else if(x.x[i] > ns[b].mx[i]) sum += x.x[i] - ns[b].mx[i];
}
return sum;
}
int query(int o) {
int l = lc[o], r = rc[o], ans = ns[o] * x;
int d1 = calc(l), d2 = calc(r);
if(d1 < d2) {
if(ans > d1) ans = min(ans, query(l));
if(ans > d2) ans = min(ans, query(r));
}
else {
if(ans > d2) ans = min(ans, query(r));
if(ans > d1) ans = min(ans, query(l));
}
return ans;
}
int main() {
// freopen("data.in", "r", stdin);
// freopen("data.out", "w", stdout);
ns[0].mx[0] = ns[0].mx[1] = -oo;
ns[0].mn[0] = ns[0].mn[1] = oo;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d%d", &ns[i].x[0], &ns[i].x[1]);
build(root, 1, n, 0);
// for(int i = 1; i <= n; i++) printf("%d %d %d %d %d %d\n", ns[i].x[0], ns[i].x[1], ns[i].mx[0], ns[i].mx[1], ns[i].mn[0], ns[i].mn[1]);
// for(int i = 1; i <= n; i++) printf("%d %d\n", lc[i], rc[i]);
int CNT = 0;
while(m--) {
int tp = read();
x.x[0] = read(); x.x[1] = read();
if(tp == 1) {
Ins(root, 0);
CNT++;
if(CNT == 10000) build(root, 1, n, 0);
}
if(tp == 2) printf("%d\n", query(root));
}
return 0;
}

浙公网安备 33010602011771号