本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

Description

为了写论文,Alex经常要整理大量的数据。 这一次,Alex面临一个严峻的考验:他需要实现一个数据结构来维护一个点集。 
现在,二维平面上有N个点。Alex 需要实现以下三种操作: 
1. 在点集里添加一个点; 
2. 给出一个点,查询它到点集里所有点的曼哈顿距离的最小值; 
3. 给出一个点,查询它到点集里所有点的曼哈顿距离的最大值。 
两个点的曼哈顿距离定义为它们的横坐标差的绝对值与纵坐标差的绝对值的和。这么困难的问题,Alex当然不会做,只好再次请你帮忙了。 

Input

第一行包含一个整数N,表示点集最初的点数。 
接下来N行,每行两个整数,依次表示每个点的横坐标和纵坐标。 
第N+2行包含一个整数Q,表示询问的数目。 
接下来Q行,每行三个整数,依次表示询问的类型,点的横坐标和纵坐标。0类型表示添加一个点,1类型表示查询到该点的曼哈顿距离的最小值,2类型表示查询最大值。 
1 ≤ N, Q ≤ 100,000,点的坐标是不超过10^9的非负整数

Output

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

Sample Input

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

Sample Output

1
2
4
3
 
 
正解:kd-tree
解题报告:
  kd-tree模板题。学习kd-tree出门右转:http://www.cnblogs.com/ljh2000-jump/tag/kd-tree/
  然而这道题我的常数无比巨大,实在找不到问题......  
 
//It is made by ljh2000
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 200011;
const int inf = 2000000001;
int n,m,nowD,root,ql,qr,ans;
struct KDTree{ int d[2],Min[2],Max[2],l,r; }t[MAXN];
inline bool cmp(KDTree q,KDTree qq){ if(q.d[nowD]==qq.d[nowD]) return q.d[nowD^1]<qq.d[nowD^1]; return q.d[nowD]<qq.d[nowD]; }
inline void init(int x){ for(int i=0;i<2;i++) t[x].Min[i]=t[x].Max[i]=t[x].d[i]; }
inline int count_min(int x){
int dd=0;
if(t[x].Min[0]>ql) dd+=t[x].Min[0]-ql;
if(t[x].Max[0]<ql) dd+=ql-t[x].Max[0];
if(t[x].Min[1]>qr) dd+=t[x].Min[1]-qr;
if(t[x].Max[1]<qr) dd+=qr-t[x].Max[1];
return dd;
}
inline int count_max(int x){ return max(abs(t[x].Min[0]-ql),abs(t[x].Max[0]-ql))+max(abs(t[x].Min[1]-qr),abs(t[x].Max[1]-qr)); }
inline int getint(){
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} inline void update(int x){
int l=t[x].l,r=t[x].r;
if(l) {
if(t[l].Min[0]<t[x].Min[0]) t[x].Min[0]=t[l].Min[0];
if(t[l].Max[0]>t[x].Max[0]) t[x].Max[0]=t[l].Max[0];
if(t[l].Min[1]<t[x].Min[1]) t[x].Min[1]=t[l].Min[1];
if(t[l].Max[1]>t[x].Max[1]) t[x].Max[1]=t[l].Max[1];
}
if(r) {
if(t[r].Min[0]<t[x].Min[0]) t[x].Min[0]=t[r].Min[0];
if(t[r].Max[0]>t[x].Max[0]) t[x].Max[0]=t[r].Max[0];
if(t[r].Min[1]<t[x].Min[1]) t[x].Min[1]=t[r].Min[1];
if(t[r].Max[1]>t[x].Max[1]) t[x].Max[1]=t[r].Max[1];
}
} inline int build(int l,int r,int D){
nowD=D; int mid=(l+r)>>1; nth_element(t+l+1,t+mid+1,t+r+1,cmp);
if(l<mid) t[mid].l=build(l,mid-1,D^1);
if(mid<r) t[mid].r=build(mid+1,r,D^1);
init(mid); update(mid);
return mid;
} inline void insert(){
int u=root; int D=0;
while(1) {
if(t[u].Min[0]>t[n].d[0]) t[u].Min[0]=t[n].d[0];
if(t[u].Max[0]<t[n].d[0]) t[u].Max[0]=t[n].d[0];
if(t[u].Min[1]>t[n].d[1]) t[u].Min[1]=t[n].d[1];
if(t[u].Max[1]<t[n].d[1]) t[u].Max[1]=t[n].d[1]; if(t[n].d[D]<=t[u].d[D]) {
if(!t[u].l) { t[u].l=n; return ; }
else u=t[u].l;
}
else{
if(!t[u].r) { t[u].r=n; return ; }
else u=t[u].r;
}
D^=1;
}
} inline void query_max(int u){
int dl=0,dr=0,dd=abs(t[u].d[0]-ql)+abs(t[u].d[1]-qr); if(dd>ans) ans=dd;
if(t[u].l) dl=count_max(t[u].l); if(t[u].r) dr=count_max(t[u].r);
if(dl>dr) {
if(dl>ans) query_max(t[u].l);
if(dr>ans) query_max(t[u].r);
}
else{
if(dr>ans) query_max(t[u].r);
if(dl>ans) query_max(t[u].l);
}
} inline void query_min(int u){
int dl=inf,dr=inf,dd=abs(t[u].d[0]-ql)+abs(t[u].d[1]-qr); if(dd<ans) ans=dd;
if(t[u].l) dl=count_min(u); if(t[u].r) dr=count_min(u);
if(dl<dr) {
if(dl<ans) query_min(t[u].l);
if(dr<ans) query_min(t[u].r);
}
else{
if(dr<ans) query_min(t[u].r);
if(dl<ans) query_min(t[u].l);
}
} inline void work(){
n=getint(); for(int i=1;i<=n;i++) t[i].d[0]=getint(),t[i].d[1]=getint();
root=build(1,n,0); m=getint(); int ljh,x,y;
while(m--) {
ljh=getint(); x=getint(); y=getint();
if(ljh==0) { t[++n].d[0]=x; t[n].d[1]=y; init(n); insert(); }
else if(ljh==1) {
ql=x; qr=y; ans=abs(t[1].d[0]-ql)+abs(t[1].d[1]-qr);
query_min(root);
printf("%d\n",ans);
}
else{
ql=x; qr=y; ans=abs(t[1].d[0]-ql)+abs(t[1].d[1]-qr);
query_max(root);
printf("%d\n",ans);
}
}
} int main()
{
work();
return 0;
}

  

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

  1. BZOJ4532: [BeiJing2014 WinterCamp] 珠链

    Description Alex喜欢玩网络游戏,认为这是智力和体力的综合锻炼.在一次游戏活动中,他意外获得了一个传说中威力极其强大的法宝:珠链.  珠链,顾名思义,就是由许多小珠子串起来的一条链.珠子 ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  3. bzoj1874 [BeiJing2009 WinterCamp]取石子游戏

    1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 925  Solved: 381[ ...

  4. Hadoop 中利用 mapreduce 读写 mysql 数据

    Hadoop 中利用 mapreduce 读写 mysql 数据   有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...

  5. App开发:模拟服务器数据接口 - MockApi

    为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...

  6. 使用TSQL查询和更新 JSON 数据

    JSON是一个非常流行的,用于数据交换的文本数据(textual data)格式,主要用于Web和移动应用程序中.JSON 使用“键/值对”(Key:Value pair)存储数据,能够表示嵌套键值对 ...

  7. SQL Server 大数据搬迁之文件组备份还原实战

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 解决方案(Solution) 搬迁步骤(Procedure) 搬迁脚本(SQL Codes) ...

  8. SQLSERVER将一个文件组的数据移动到另一个文件组

    SQLSERVER将一个文件组的数据移动到另一个文件组 有经验的大侠可以直接忽视这篇文章~ 这个问题有经验的人都知道怎麽做,因为我们公司的数据量不大没有这个需求,也不知道怎麽做实验 今天求助了QQ群里 ...

  9. 【.net 深呼吸】设置序列化中的最大数据量

    欢迎收看本期的<老周吹牛>节目,由于剧组严重缺钱,故本节目无视频无声音.好,先看下面一个类声明. [DataContract] public class DemoObject { [Dat ...

随机推荐

  1. IOS开发之Bug--View是懒加载导致出误以为是UI加载的bug

    虽然分类为bug,但也算的上是一个问题,一个很简单的问题.先来看看问题的重现,就写了简单的Demo验证效果: 问题:点击ViewController跳转到TwoViewController,发现会延迟 ...

  2. IOS-WebViewJavascriptBridge使用说明

    下面来说一下WebViewJavascriptBridge在ios端怎么样使用. 首先确保一份已经配好功能的html文件. 1.初始化一个webview(viewdidload) UIWebView* ...

  3. jquery 获取多个select name 的值

    html {foreach from=$month_arr item=dateArr key=i}<tr> <td>{$dateArr.m}</td> <td ...

  4. #研发解决方案介绍#Tracing(鹰眼)

    郑昀 最后更新于2014/11/12 关键词:GoogleDapper.分布式跟踪.鹰眼.Tracing.HBase.HDFS. 本文档适用人员:研发   分布式系统为什么需要 Tracing?   ...

  5. SqlException 当前命令发生了严重错误 应放弃任何可能产生的结果

    今天在信息发布功能时出现了一个怪异的错误(时而出错,时而不会): System.Data.SqlClient.SqlException: 当前命令发生了严重错误.应放弃任何可能产生的结果. >& ...

  6. CMS本质上是什么

    2015-121.数据可以任意取和构造,结构也很自由,不一定是“站点-栏目-文章-评论”.2.主要用于显示,前台不产生数据(评论.浏览次数除外).3.在模版进行循环.判断,也比后台写代码要方便很多很多 ...

  7. 0027 Java学习笔记-面向对象-(非静态、静态、局部、匿名)内部类

    内部类 内部类就是把一个类写在另一个类的内部 用途: 如果一个类只希望它被某一个类访问,那么可以把它定义在另一个类的内部,并用private修饰 内部类可以访问它所在外部类的private成员:但所在 ...

  8. PostgreSQL-角色、库、模式、表

    由于不了解postgresql的psql工具,安装完数据库后就直接用pgadmin或navicat来连接操作,在确认初始化后的库中默认有些什么东西后竟然一直无处下手,在还没有了解pg大致体系的情况下搞 ...

  9. 解决webkit浏览器中js方法中使用window.event提示未定义的问题

    这实际上是一个浏览器兼容性问题,根源百度中一大堆,简要说就是ie中event对象是全局变量,所以哪里都能使用到,但是webkit内核的浏览器中却不存在这个全局变量event,而是以一个隐式的局部变量的 ...

  10. struts2的拦截器(Interceptor)与过滤器(Filter)

    一.拦截器与过滤器的区别: 1.filter基于回调函数,我们需要实现的filter接口中doFilter方法就是回调函数,而interceptor则基于Java本身的反射机制,这是两者最本质的区别. ...