[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;
}

 

posted @ 2016-08-06 18:59  xjr01  阅读(250)  评论(0编辑  收藏  举报