【Tsinsen】【A1365】森林旅店
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 ;
}
不过有一个问题一直困扰着小H的计划,那就是森林中白蚁泛滥。大家都知道白蚁对于树木和木制品的危害,如果建造的房子周围白蚁成灾,那无疑就是将游客的人身安全置于一个危险的境地中了。因此小H在建造小屋的时候必须更加合理地考量房子的安全性。
简而言之,我们可以认为森林里有许多的树木,其中有N个白蚁穴在这些树木上。在同一棵树上最多只有一个白蚁穴。
小H想知道,如果他希望在某棵树上建立一座小屋,那么周围离它最近的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)建造一个小屋,请告知周边的蚁穴情况。
0 0
Q 0 2
A 0 3
Q 0 2
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】森林旅店的更多相关文章
- 协议森林16 小美的桌号(DHCP协议)
作者:Vamei 出处:http://www.cnblogs.com/vamei 转载请先与我联系. DHCP协议用于动态的配置电脑的网络相关参数,如主机的IP地址,路由器出口地址.DNS域名服务器地 ...
- scikit-learn随机森林调参小结
在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结.本文就从实践的角度对RF做一个总结.重点讲述scikit-learn中RF的调参注 ...
- Bagging与随机森林算法原理小结
在集成学习原理小结中,我们讲到了集成学习有两个流派,一个是boosting派系,它的特点是各个弱学习器之间有依赖关系.另一种是bagging流派,它的特点是各个弱学习器之间没有依赖关系,可以并行拟合. ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- Tsinsen A1493 城市规划(DP + CDQ分治 + NTT)
题目 Source http://www.tsinsen.com/A1493 Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在 ...
- Step by step 如何创建一个新森林
原创地址:http://www.cnblogs.com/jfzhu/p/4006118.html 转载请注明出处 创建一个新森林就是在一台计算机上安装AD DS,并将这台计算机提升为域控制器. 演示环 ...
- [Machine Learning & Algorithm] 随机森林(Random Forest)
1 什么是随机森林? 作为新兴起的.高度灵活的一种机器学习算法,随机森林(Random Forest,简称RF)拥有广泛的应用前景,从市场营销到医疗保健保险,既可以用来做市场营销模拟的建模,统计客户来 ...
- 使用脚本自动配置matlab安装libsvm和随机森林工具箱
前言 支持向量机(SVM)和随机森林 都是用于分类的机器学习算法. 这里我需要对网上的工具箱在matlab中进行配置. 效果演示: 1.双击运行“自动配置.bat” 2.matlab会自动启动,手动配 ...
随机推荐
- PHP二维数组根据某个键名排序
$result = array( array( "amount": "11.00", "date": ...
- Java实现抽奖游戏
代码如下: import java.io.*; public class PresentDemo { /** * @param args */ public static void main(Stri ...
- dump buffer cache
1.基础内容: ALTER SESSION SET EVENTS 'immediate trace name buffers level n'; n取值意义: 1 只转储buffer header. ...
- 相比于汇编语言的准确性c语言延时精确度如何提升
只要合理的运用,C还是可以达到意想不到的效果.很多朋友抱怨C效率比汇编差了很多,其实如果对Keil C的编译原理有一个较深入的理解,是可以通过恰当的语法运用,让生成的C代码达到最优化.即使这看起来不大 ...
- ok6410的madplay配置
二.移植嵌入式播放器 madplay madplay 播放器程序主要依赖于如下库: zlib zlib-1.1.4.tar.gz 提供数据压缩用的函式库 libid3tag libid3tag- ...
- 第六章 管理类型(In .net4.5) 之 创建类型
1. 概述 本章内容包括 C#5中如何更好的创建类型以及如何扩展现有类型. 2. 主要内容 2.1 如何选择类型 C#类型系统包括三种类型:值类型.引用类型.指针类型.(指针类型用于非托管代码,很少使 ...
- 解决在sublime text3在ubuntu下无法输入中文的问题
方法链接:https://github.com/lyfeyaj/sublime-text-imfix 效果图:
- ruby 笔记
symbol 不能有- 'data-turbolinks-track' => true stop rails –s kill -INT $(cat tmp/pids/server.pid) cl ...
- linux积累
在多文件中批量替换字符串grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'
- Unity Scripting Tutorials 要点记录
(搬运自我在SegmentFault的博客) 这几天通过Unity官网的Unity Scripting Tutorials的视频学习Unity脚本,观看的过程中做了记录.现在,整理了一下笔记,供自己以 ...