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. IMAP收邮件

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  2. js各种宽高(1)

    在javascript中操作dom节点让其运动的时候,常常会涉及到各种宽高以及位置坐标等概念,如果不能很好地理解这些属性所代表的意义,就不能理解js的运动原理,同时,由于这些属性概念较多,加上浏览器之 ...

  3. STM32F0xx_看门狗(独立+窗口)配置详细过程

    Ⅰ.概述 对于看门狗,我觉得做单片机或者嵌入式开发的人员来说并不陌生,今天总结STM32F0看门狗的功能,F0的看门狗有两种:独立和窗口看门狗. 今天提供两种看门狗的软件工程实例,供大家下载. 两种看 ...

  4. 避免url传值字符串sjstr过长,使用from表单【隐藏域】post提交

    1.普通的url传值<html--------------- <!-- 隐藏域post提交url --> <form id="urlPost" action ...

  5. C#(HTML)_小技巧_关于textbox框中不能输入HTML标签的解决方法(如输入“<p>”后,在提交表单时系统会崩溃)

    主要修改文件是config文件(Web.config): 1.在<pages>标签中添加属性:validateRequest="false" <pages val ...

  6. Windows Phone动画

    从事Windows Phone开发已经有一段时间了,但是一直没有好好的静下心来梳理一下自己这段时间的知识,一是怕自己学问不到家,写不出那些大牛一般的高屋建瓴:二是以 前一直没有写博客的习惯:好了废话不 ...

  7. ios中怎么样点击背景退出键盘

    //退出键盘 只需一句,药到病除 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ [self.view endEdi ...

  8. 基于Elasticsearch的自定义评分算法扩展

    实现思路: 重写评分方法,调整计算文档得分的过程,然后根据function_score或script_sort进行排序检索.   实现步骤: 1.新建java项目TestProject,引入Elast ...

  9. mvc中使用knockoutjs和ajax

    虽然说knockoutjs 官网上写的非常的清楚!但是像我这样的英语呕吐患者,真是虐心啊!今天我写下做个记录,也为那些初次使用的同学给予帮助, 首先我说一下今天我说的内容只是应用不做原理探究,如果没有 ...

  10. wpa_supplicant 使用

    (1)通过adb命令行,可以直接打开supplicant,从而运行wpa_cli,可以解决客户没有显示屏而无法操作WIFI的问题,还可以避免UI的问题带到driver.进一步来说,可以用在很多没有键盘 ...