KD-Tree


  啊哈~检验了一下自己KD-Tree的学习情况,还算可以,模板至少是记下来了。

  支持插入(所以要带重建),查询最近的P个点的距离。

  然而题目并没有说是按怎样的顺序输出这P个点?。。。(事实上是从近到远)

  没啥好讲的……就是KD-Tree的裸操作……

     //Tsinsen A1365
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
inline int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=2e5+;
typedef long long LL;
const LL INF=1e9;
/******************tamplate*********************/
int n,m,K,P,D,p[N],cnt,tot,root;
struct node{
int d[],mn[],mx[],l,r,D,size;
int& operator [] (int x){return d[x];}
void read(){d[]=getint();d[]=getint();}
}t[N],tmp;
inline bool cmp(int x,int y){return t[x][D]<t[y][D];}
#define L t[o].l
#define R t[o].r
#define mid (l+r>>1)
void Push_up(int o){
F(i,,){
t[o].mn[i]=min(t[o][i],min(t[L].mn[i],t[R].mn[i]));
t[o].mx[i]=max(t[o][i],max(t[L].mx[i],t[R].mx[i]));
}
t[o].size=t[L].size+t[R].size+;
}
int build(int l,int r,int dir){
D=dir;
nth_element(p+l,p+mid,p+r+,cmp);
int o=p[mid];
t[o].D=dir;
L=l<mid?build(l,mid-,dir^):;
R=r>mid?build(mid+,r,dir^):;
Push_up(o);
return o;
}
void dfs(int o){
if (!o) return;
dfs(L);
p[++cnt]=o;
dfs(R);
}
void rebuild(int &o){
cnt=;
dfs(o);
o=build(,cnt,t[o].D);
}
void Insert(int &o,int dir){
if (!o){
o=++tot; t[o]=tmp;
F(i,,) t[o].mn[i]=t[o].mx[i]=t[o][i];
t[o].D=dir; t[o].size=;
}else{
if (tmp[dir]<t[o][dir]){
Insert(L,dir^); Push_up(o);
if ((double)t[L].size>(double)t[o].size*0.7) rebuild(o);
}else{
Insert(R,dir^); Push_up(o);
if ((double)t[R].size>(double)t[o].size*0.7) rebuild(o);
}
}
}
inline LL get(LL v){
if (K==) return abs(v);
else return v*v;
}
inline double ANS(LL v){
if (K==) return v;
else return sqrt(double(v));
}
inline LL getdis(int o){
if (!o) return 1e16;
LL ans=;
F(i,,){
if (t[o].mn[i]>tmp[i]) ans+=get(t[o].mn[i]-tmp[i]);
if (t[o].mx[i]<tmp[i]) ans+=get(tmp[i]-t[o].mx[i]);
}
return ans;
}
inline LL dis(int o){return get(t[o][]-tmp[])+get(t[o][]-tmp[]);}
priority_queue<LL>Q;
void query(int o){
if (!o) return;
LL dl=getdis(L),dr=getdis(R),d0=dis(o);
if (d0<Q.top()){Q.pop(); Q.push(d0);}
if (dl<dr){
if (dl<Q.top()) query(L);
if (dr<Q.top()) query(R);
}else{
if (dr<Q.top()) query(R);
if (dl<Q.top()) query(L);
}
}
double ans[];
int main(){
#ifndef ONLINE_JUDGE
freopen("A1365.in","r",stdin);
freopen("A1365.out","w",stdout);
#endif
F(i,,) t[].mn[i]=INF,t[].mx[i]=-INF;
t[].size=;
tot=n=getint(); m=getint(); K=getint(); P=getint();
F(i,,n) {t[i].read(); p[i]=i;}
root=build(,n,);
char cmd[];
F(i,,m){
scanf("%s",cmd);
tmp.read();
if (cmd[]=='Q'){
F(j,,P) Q.push(1e16);
query(root);
D(j,P,){
ans[j]=ANS(Q.top());
Q.pop();
}
F(j,,P)
printf("%.4f%c",ans[j],j==P ? '\n' : ' ');
}else{
Insert(root,);
}
}
return ;
}
A1365. 森林旅店
时间限制:1.0s   内存限制:256.0MB  
总提交次数:817   AC次数:58   平均分:37.59
将本题分享到:
   
试题来源
  清华大学2012年信息学优秀高中学子夏令营
问题描述
  小H家旁边的树林可是一年四季度假的好地方。为了整合资源扩大效益,小H打算在树林中建立一些“泰山的小屋”,即在一些树木上建造一些小屋,让大家更加近距离地体会自然的美。
  不过有一个问题一直困扰着小H的计划,那就是森林中白蚁泛滥。大家都知道白蚁对于树木和木制品的危害,如果建造的房子周围白蚁成灾,那无疑就是将游客的人身安全置于一个危险的境地中了。因此小H在建造小屋的时候必须更加合理地考量房子的安全性。
  简而言之,我们可以认为森林里有许多的树木,其中有N个白蚁穴在这些树木上。在同一棵树上最多只有一个白蚁穴。
  小H想知道,如果他希望在某棵树上建立一座小屋,那么周围离它最近的P 个白蚁穴的距离分别是多少呢?
  同时由于随时可能发现新的白蚁穴,你的程序还应该支持动态地加入新发现的蚁穴。
输入格式
  第一行包含四个整数N,Q,K和P。 N为初始时的白蚁穴数量,Q是操作数量,K是距离度量函数的参数,P为每次查询要输出的蚁穴个数。

  对于坐标位置为(X_1,Y_1 )和(X_2,Y_2 )的距离,我们定义为:

  (|X_1-X_2 |^K + |Y_1-Y_2 |^K )^(1/K)

  接下来N行,每行两个整数,表示初始时白蚁穴的坐标。

  再接下来Q行,每行有一个字符C和两个整数X和Y。字符C是‘A’表示加入一个坐标为(X,Y)的白蚁穴,‘Q’表示询问如果在(X,Y)建造一个小屋,请告知周边的蚁穴情况。

输出格式
  对于每组询问,输出P 个实数,以单个空格隔开,表示距离最近的 个蚁穴的距离,精确到小数点后4位。
样例输入
1 3 1 1
0 0
Q 0 2
A 0 3
Q 0 2
样例输出
2.0000
1.0000
数据规模和约定
  本题的测试数据均以以下方式生成。

  假设所有出现的蚁穴是:{(X_i,Y_i )}, 1≤i≤M。设函数f(x), g(x)是两个单调函数。数据生成方法如下:

  1.生成M个随机点(x_i,y_i),满足0≤ x_i,y_i≤1;
  2.最终输入数据为X_i=f(x_i ),Y_i=g(y_i ),且满足0≤ X_i,Y_i≤10^7。

  测试数据共分10组,每组包括5个测试点,共50个测试点。同一组的5个测试数据的蚁穴的初始位置由同一组随机点经不同的函数变换产生。

  测试数据组 1 2 3 4 5
  N 5,000 20,000 100,000 100,000 20,000
  Q 2,000 10,000 5,000 20,000 2,000
  K 1 1 1 1 2
  P 1 3 3 3 1
  测试数据组 6 7 8 9 10
  N 20,000 100,000 100,000 100,000 100,000
  Q 20,000 5,000 20,000 20,000 20,000
  K 2 2 2 2 2
  P 3 3 3 3 3
  表中所有数据均为数据上界。
  每组测试点集合中 的数据不包含插入操作。
  所有数据中查询次数不超过5,000次。

 

【Tsinsen】【A1365】森林旅店的更多相关文章

  1. 协议森林16 小美的桌号(DHCP协议)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 转载请先与我联系. DHCP协议用于动态的配置电脑的网络相关参数,如主机的IP地址,路由器出口地址.DNS域名服务器地 ...

  2. scikit-learn随机森林调参小结

    在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结.本文就从实践的角度对RF做一个总结.重点讲述scikit-learn中RF的调参注 ...

  3. Bagging与随机森林算法原理小结

    在集成学习原理小结中,我们讲到了集成学习有两个流派,一个是boosting派系,它的特点是各个弱学习器之间有依赖关系.另一种是bagging流派,它的特点是各个弱学习器之间没有依赖关系,可以并行拟合. ...

  4. 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

    图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...

  5. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  6. Tsinsen A1493 城市规划(DP + CDQ分治 + NTT)

    题目 Source http://www.tsinsen.com/A1493 Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在 ...

  7. Step by step 如何创建一个新森林

    原创地址:http://www.cnblogs.com/jfzhu/p/4006118.html 转载请注明出处 创建一个新森林就是在一台计算机上安装AD DS,并将这台计算机提升为域控制器. 演示环 ...

  8. [Machine Learning & Algorithm] 随机森林(Random Forest)

    1 什么是随机森林? 作为新兴起的.高度灵活的一种机器学习算法,随机森林(Random Forest,简称RF)拥有广泛的应用前景,从市场营销到医疗保健保险,既可以用来做市场营销模拟的建模,统计客户来 ...

  9. 使用脚本自动配置matlab安装libsvm和随机森林工具箱

    前言 支持向量机(SVM)和随机森林 都是用于分类的机器学习算法. 这里我需要对网上的工具箱在matlab中进行配置. 效果演示: 1.双击运行“自动配置.bat” 2.matlab会自动启动,手动配 ...

随机推荐

  1. 开始安装 ASP.NET (4.0.30319.18408)。 出现了错误: 0x8007b799 必须具有此计算机的管理员权限才能运行此工具

    在Visual Studio命令提示符安装ASP.NET .出现了错误: 0x8007b799 必须具有此计算机的管理员权限才能运行此工具:如下图: 解决方案如下: 1.打开“C:\Windows\S ...

  2. asp.net mvc razor html encoding

    HTML Encoding 为了跨站点的脚本攻击,Razor 语法会直接将脚本代码编码输出. @{string message = "<script>alert('haacked ...

  3. Perl 随机数和随机密码的产生

    Perl有着强大的随机数产生函数rand(),下面的代码详细介绍其应用 #!/usr/bin/perl #  use strict;   use warnings; # 0~1之间    $rando ...

  4. View和监听器

    View的基本概念 View就是Activity当中显示出来的控件,用对象来表示,如文本框的TextView类,按钮的Button类等等 每一种控件都对应一个类,都属于View的子类 在Activit ...

  5. hdu 5273 Dylans loves sequence

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5273 Dylans loves sequence Description Dylans is give ...

  6. hdu 2091 空心三角形

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2091 空心三角形 Description 把一个字符三角形掏空,就能节省材料成本,减轻重量,但关键是为 ...

  7. JavaScript高级程序设计之基本包装类型

    为便于操作基本类型值,ECMAScript提供了3个特殊的引用类型:Boolean, Number 和 String // 字符串怎么会有方法呢 var str1 = "some text& ...

  8. sychronized面试问题浅析

    先说下面试吧,整体来说基础准备好点,简历别太假,然后回答起来实事求是,表现自然的点基本上都没问题吧(针对初级职位,记得有个hr说过对于新人基础扎实和为人真诚是最关键的),两天时间跑起来挺累,反而觉得面 ...

  9. Objective-C 一些概念

    Automatic Reference Counting (ARC)

  10. maven学习手记 - 3

    学习目标 maven插件的定义: maven插件的使用.   前言 在手记2中说过maven的阶段命令是通过插件实现的.在手记1中也有简单的示范过插件的用法.但是总觉得有些泛泛了,想在这里再捋一下,以 ...