[BZOJ4533][BeiJing2014 WinterCamp] 数据

试题描述

为了写论文,Alex经常要整理大量的数据。 这一次,Alex面临一个严峻的考验:他需要实现一个数据结构来维护一个点集。

现在,二维平面上有N个点。Alex 需要实现以下三种操作:

1. 在点集里添加一个点;

2. 给出一个点,查询它到点集里所有点的曼哈顿距离的最小值;

3. 给出一个点,查询它到点集里所有点的曼哈顿距离的最大值。

两个点的曼哈顿距离定义为它们的横坐标差的绝对值与纵坐标差的绝对值的和。这么困难的问题,Alex当然不会做,只好再次请你帮忙了。

输入

第一行包含一个整数N,表示点集最初的点数。

接下来N行,每行两个整数,依次表示每个点的横坐标和纵坐标。

第N+2行包含一个整数Q,表示询问的数目。

接下来Q行,每行三个整数,依次表示询问的类型,点的横坐标和纵坐标。0类型表示添加一个点,1类型表示查询到该点的曼哈顿距离的最小值,2类型表示查询最大值。

1 ≤ N, Q ≤ 100,000,点的坐标是不超过10^9的非负整数

输出

输出若干行,依次表示每个查询操作的答案。

输入示例

3
7 5
6 2
3 1
5
1 6 1
1 5 5
2 7 1
0 3 2
1 1 0

输出示例

1
2
4
3

数据规模及约定

见“输入

题解

这道题kd树踩标程,我借此学了学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 200010
#define oo 2147483647
int n, lc[maxn], rc[maxn];
int ToT, Cur, root;
struct Node {
	int x[2], mx[2], mn[2];
	bool operator < (const Node& t) const { return x[Cur] < t.x[Cur]; }
} nodes[maxn];

void maintain(int o) {
	int l = lc[o], r = rc[o];
	for(int i = 0; i < 2; i++) {
		nodes[o].mx[i] = max(max(nodes[l].mx[i], nodes[r].mx[i]), nodes[o].x[i]);
		nodes[o].mn[i] = min(min(nodes[l].mn[i], nodes[r].mn[i]), nodes[o].x[i]);
	}
	return ;
}
void build(int& o, int L, int R, int cur) {
	if(L > R) return ;
	int M = L + R >> 1; o = M;
	Cur = cur; nth_element(nodes + L, nodes + M, nodes + R + 1);
	build(lc[o], L, M - 1, cur ^ 1); build(rc[o], M + 1, R, cur ^ 1);
	maintain(o);
	return ;
}
Node no;
void insert(int& o, int cur) {
	if(!o) nodes[o = ++ToT] = no;
	else insert(no.x[cur] < nodes[o].x[cur] ? lc[o] : rc[o], cur ^ 1);
	maintain(o);
	return ;
}
int calcmn(int o) {
	int ans = 0;
	for(int i = 0; i < 2; i++) {
		if(nodes[o].mn[i] > no.x[i]) ans += nodes[o].mn[i] - no.x[i];
		if(nodes[o].mx[i] < no.x[i]) ans += no.x[i] - nodes[o].mx[i];
	}
	return ans;
}
int querymn(int& o) {
	int ans = oo;
	if(!o) return ans;
	ans = min(ans, abs(no.x[0] - nodes[o].x[0]) + abs(no.x[1] - nodes[o].x[1]));
	int dl = calcmn(lc[o]), dr = calcmn(rc[o]);
	if(dl < dr) {
		if(dl < ans) ans = min(ans, querymn(lc[o]));
		if(dr < ans) ans = min(ans, querymn(rc[o]));
	}
	else {
		if(dr < ans) ans = min(ans, querymn(rc[o]));
		if(dl < ans) ans = min(ans, querymn(lc[o]));
	}
	return ans;
}
int calcmx(int o) {
	return max(abs(nodes[o].mx[0] - no.x[0]), abs(nodes[o].mn[0] - no.x[0])) + max(abs(nodes[o].mx[1] - no.x[1]), abs(nodes[o].mn[1] - no.x[1]));
}
int querymx(int& o) {
	int ans = -oo;
	if(!o) return ans;
	ans = max(ans, abs(no.x[0] - nodes[o].x[0]) + abs(no.x[1] - nodes[o].x[1]));
	int dl = calcmx(lc[o]), dr = calcmx(rc[o]);
	if(dl > dr) {
		if(dl > ans) ans = max(ans, querymx(lc[o]));
		if(dr > ans) ans = max(ans, querymx(rc[o]));
	}
	else {
		if(dr > ans) ans = max(ans, querymx(rc[o]));
		if(dl > ans) ans = max(ans, querymx(lc[o]));
	}
	return ans;
}

int main() {
	nodes[0].mx[0] = nodes[0].mx[1] = -oo;
	nodes[0].mn[0] = nodes[0].mn[1] = oo;
	n = read();
	for(int i = 1; i <= n; i++) {
		ToT++;
		nodes[ToT].x[0] = read();
		nodes[ToT].x[1] = read();
	}

	build(root, 1, n, 0);
	int q = read();
	while(q--) {
		int tp = read();
		no.x[0] = read();
		no.x[1] = read();
		if(!tp) insert(root, 0);
		if(tp == 1) printf("%d\n", querymn(root));
		if(tp == 2) printf("%d\n", querymx(root));
	}

	return 0;
}
时间: 2024-08-06 11:31:49

[BZOJ4533][BeiJing2014 WinterCamp] 数据的相关文章

BZOJ4532: [BeiJing2014 WinterCamp] 珠链

Description Alex喜欢玩网络游戏,认为这是智力和体力的综合锻炼.在一次游戏活动中,他意外获得了一个传说中威力极其强大的法宝:珠链. 珠链,顾名思义,就是由许多小珠子串起来的一条链.珠子有很多种颜色.Alex听说过,只有将珠链打磨纯净,珠链才能发挥最大的威力. 纯净珠链是指这样的珠链:它可以分成若干个长度相等的段,使任何两段的任何相同位置的珠子的颜色均不同,相同位置指珠子在段内的相对位置相同:而且每段的长度以及划分的段数也是有规范的,Alex记得,每段包含的珠子数目必须在L到R之间,

【BZOJ 1874】 [BeiJing2009 WinterCamp]取石子游戏

1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 473  Solved: 186 [Submit][Status] Description 小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问你他是否有必胜策略,如果有,第一步如何取石子. Input 输

记一次MySQL找回用户数据

事情经过 有天,我们公司外区的一个销售C说他8月3号以前的工作流记录找不到了.问清缘由,原来是更新了微信号(我们公司的工作流是基于企业微信开发的).经过分析,微信号和流程数据并没什么关系,所以初步得出结论:本来只需要更新微信号的,结果我们公司的流程系统管理员把用户先删除,再创建了新的用户. 解决过程 1.首先想到的是直接从定时备份数据里面找回原来的用户ID,结果发现系统只备份了十天的记录,而工作流系统上显示销售C只有8月3号以后的流程记录,距今已经40多天,从自动备份的数据里已经无法恢复. 2.

使用 Chrome 浏览器插件 Web Scraper 10分钟轻松实现网页数据的爬取

本文标签: WebScraper Chrome浏览器插件 网页数据的爬取 使用Chrome 浏览器插件 Web Scraper 可以轻松实现网页数据的爬取,不写代码,鼠标操作,点哪爬哪,还不用考虑爬虫中的登陆.验证码.异步加载等复杂问题. Web Scraper插件 Web Scraper 官网中的简介: Web Scraper Extension (Free!)Using our extension you can create a plan (sitemap) how a web site

Day4 - 迭代器&amp;生成器、装饰器、Json &amp; pickle 数据序列化、软件目录结构规范

---恢复内容开始--- 本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 需求:列表a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],要求把列表里的每个值加1 1 a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 2 b = [] 3 for i in a: 4 b.append(i+1) 5 a = b 6 print(a) 普通青

Oracle 10g通过创建物化视图实现不同数据库间表级别的数据同步

摘自:http://blog.csdn.net/javaee_sunny/article/details/53439980 目录(?)[-] Oracle 10g 物化视图语法如下 实例演示 主要步骤 在A节点创建原表和物化视图日志 在B节点创建连接A节点的远程链接 在B节点处创建目标表和与目标表名称相同的物化视图 在B节点处刷新物化视图 升级采用存储过程定时任务JOB方式定时刷新物化视图 进一步优化 文章更新记录 参考文章 Oracle 10g 物化视图语法如下: create materia

MySQL(九)之数据表的查询详解(SELECT语法)二

上一篇讲了比较简单的单表查询以及MySQL的组函数,这一篇给大家分享一点比较难得知识了,关于多表查询,子查询,左连接,外连接等等.希望大家能都得到帮助! 在开始之前因为要多表查询,所以搭建好环境: 1)创建数据表suppliers 前面已经有一张表是book表,我们在建立一张suppliers(供应商)表和前面的book表对应. 也就是说 让book中s_id字段值指向suppliers的主键值,创建一个外键约束关系. 其实这里并没有达到真正的外键约束关系,只是模拟,让fruits中的s_id中

C#如何拿到从http上返回JSON数据?

在实际开发中,我们经常会使用到API,所谓API一般就是一个地址,我们称之为接口.然后我们通过用C#对这地址发送请求,请求后,服务器就会给我们返回数据,一般是XML或者JSON,这里我们主要讲述的是JSON. 为了演示,我们这里准备了一个接口,这是一个查询物流的接口.(读者读到这篇文章的时候,接口可能有效,也可能失效,因为接口是网上找的,不是笔者自己写的,但是原理是一样的.) 接口:  http://www.kuaidi100.com/query?type=快递公司编码&postid=物流单号

C#中导出数据到Excel表格中

之前PM交给我一个自动化测试的Case,让我抓取页面上的数据到Excel表格中,刚好又接了一个之前人家做的系统, 刚好看到可以用NPOI导数据,就动手试试,成功导出. 由于鄙人比较菜,也比较懒, 怕自己忘记了,今天就总结一下,以防下次用可以参考. 1.要使用NPOI,首先需要在Project中Install NPOI的 Package. 右键点击Project------>Manage NuGet Packages---->Search NPOI----->点击搜索到的NPOI然后点击等