[BZOJ2716][Violet 3]天使玩偶
[BZOJ2716][Violet 3]天使玩偶
试题描述
输入
输出
输入示例
第一个测试点,我就不拿来占页面了= =
输出示例
同上
数据规模及约定
= =题目中给的范围不对。。。交上去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; }