Hide and Seek bzoj-1941 Sdoi-2010

题目大意:给出平面上n个点,选出一个点,使得距离这个点的最远点曼哈顿距离减去距离这个点的最近非己点的曼哈顿距离最小。输出最小曼哈顿距离差。

注释:$1\le n \le 5\cdot 10^5$。


想法:这个题的话处理方法就是枚举所有点,然后对于每一个点求近邻点和“远”邻点。

其实区别就是估价函数的区别。近邻点对的估价函数就是SJY摆旗子的估价函数

远邻点的话我们就另设一个估价函数,就表示当前点到这个矩形的可能最远曼哈顿距离。也就是矩形的4个顶点中距离当前点曼哈顿距离最远的曼哈顿距离。

然后枚举更新答案即可。

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1000010
#define inf 0x7f7f7f7f
using namespace std;
int ans_min,ans_max,root,d;
struct Node
{
int c[2],p[2],maxn[2],minn[2];
}a[N];
inline bool cmp(const Node &a,const Node &b)
{
return a.p[d]==b.p[d]?a.p[d^1]<b.p[d^1]:a.p[d]<b.p[d];
}
void pushup(int k , int s)
{
a[k].minn[0] = min(a[k].minn[0] , a[s].minn[0]);
a[k].minn[1] = min(a[k].minn[1] , a[s].minn[1]);
a[k].maxn[0] = max(a[k].maxn[0] , a[s].maxn[0]);
a[k].maxn[1] = max(a[k].maxn[1] , a[s].maxn[1]);
}
int build(int l , int r , int now)
{
int mid = (l + r) >> 1;
d = now , nth_element(a + l , a + mid , a + r + 1 , cmp);
a[mid].minn[0] = a[mid].maxn[0] = a[mid].p[0];
a[mid].minn[1] = a[mid].maxn[1] = a[mid].p[1];
if(l < mid) a[mid].c[0] = build(l , mid - 1 , now ^ 1) , pushup(mid , a[mid].c[0]);
if(r > mid) a[mid].c[1] = build(mid + 1 , r , now ^ 1) , pushup(mid , a[mid].c[1]);
return mid;
}
int getdis_min(int qx,int qy,int x)
{
int ans=0;
if(qx<a[x].minn[0]) ans+=a[x].minn[0]-qx;
if(qx>a[x].maxn[0]) ans+=qx-a[x].maxn[0];
if(qy<a[x].minn[1]) ans+=a[x].minn[1]-qy;
if(qy>a[x].maxn[1]) ans+=qy-a[x].maxn[1];
return ans;
}
int getdis_max(int qx,int qy,int x)
{
int ans=0;
ans+=max(abs(qx-a[x].minn[0]),abs(qx-a[x].maxn[0]));
ans+=max(abs(qy-a[x].minn[1]),abs(qy-a[x].maxn[1]));
return ans;
}
void query_min(int qx,int qy,int x)
{
int dis_now=abs(qx-a[x].p[0])+abs(qy-a[x].p[1]);
if(dis_now) ans_min=min(dis_now,ans_min);
int ls=a[x].c[0],rs=a[x].c[1];
int dis_l=ls?getdis_min(qx,qy,ls):inf;
int dis_r=rs?getdis_min(qx,qy,rs):inf;
if(dis_l<dis_r)
{
if(ans_min>dis_l) query_min(qx,qy,ls);
if(ans_min>dis_r) query_min(qx,qy,rs);
}
else
{
if(ans_min>dis_r) query_min(qx,qy,rs);
if(ans_min>dis_l) query_min(qx,qy,ls);
}
}
void query_max(int qx,int qy,int x)
{
int dis_now=abs(qx-a[x].p[0])+abs(qy-a[x].p[1]);
ans_max=max(dis_now,ans_max);
int ls=a[x].c[0],rs=a[x].c[1];
int dis_l=ls?getdis_max(qx,qy,ls):0;
int dis_r=rs?getdis_max(qx,qy,rs):0;
if(dis_l>dis_r)
{
if(ans_max<dis_l) query_max(qx,qy,ls);
if(ans_max<dis_r) query_max(qx,qy,rs);
}
else
{
if(ans_max<dis_r) query_max(qx,qy,rs);
if(ans_max<dis_l) query_max(qx,qy,ls);
}
}
int main()
{
int n,ans=inf; cin >> n ;
for(int i=1;i<=n;i++) scanf("%d%d",&a[i].p[0],&a[i].p[1]);
root=build(1,n,1);
for(int i=1;i<=n;i++)
{
ans_min=inf,ans_max=0;
query_min(a[i].p[0],a[i].p[1],root), query_max(a[i].p[0],a[i].p[1],root);
ans=min(ans,ans_max-ans_min);
}
printf("%d\n",ans);
return 0;
}

小结:KD-Tree如果觉得复杂度不对就不对吧,这题就是驶过的。还有,那个tm30秒我还以为是每个店周围的斜正方形之内的点,然后一顿敲就是过不去样例,还没有样例解释...差评!

最新文章

  1. [LeetCode] Isomorphic Strings 同构字符串
  2. 基于腾讯手Q样式规范Frozen UI
  3. oracle触发器如何使用2
  4. 来认识下less css
  5. vim中设置Python自动补全
  6. jsmart 前结合案例
  7. Hadoop体系架构简介
  8. Java NIO之选择器
  9. Response ServletContext 中文乱码 Request 编码 请求行 共享数据 转发重定向
  10. 经过一段的努力,终于成为CSDN博客专家,感谢大家支持
  11. Redis的值value(数据结构类型)
  12. C#Dictionary源码
  13. 昂达 v891 连接上adb 调试
  14. 【其他】【服务器】【2】把jar包做成服务,在Service中管理
  15. git忽略未被跟踪和已被跟踪的文件
  16. rapidjson使用总结
  17. MVC的默认约定
  18. Linux--安全加固01
  19. 170425、centos安装mysql5.6数据库
  20. IE11在使用get方式提交没有进行请求的bug问题

热门文章

  1. 产生冠军(toposort)
  2. Network(Tarjan+LCA)
  3. php三方网站使用微信公众号推送文章
  4. Codeforces 769C
  5. 【Leetcode 166】 Fraction to Recurring Decimal
  6. Dancing Links X 学习笔记
  7. python round()模块
  8. 从0开始复习JS---1、函数复习
  9. C++ 中 字符数组 和 指针 区别
  10. 学习MPI并行编程记录