【Tsinsen】【A1365】森林旅店

KD-Tree



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

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

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

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

  1     //Tsinsen A1365
  2     #include<cmath>
  3     #include<queue>
  4     #include<vector>
  5     #include<cstdio>
  6     #include<cstring>
  7     #include<cstdlib>
  8     #include<iostream>
  9     #include<algorithm>
 10     #define rep(i,n) for(int i=0;i<n;++i)
 11     #define F(i,j,n) for(int i=j;i<=n;++i)
 12     #define D(i,j,n) for(int i=j;i>=n;--i)
 13     #define pb push_back
 14     using namespace std;
 15     inline int getint(){
 16         int v=0,sign=1; char ch=getchar();
 17         while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();}
 18         while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();}
 19         return v*sign;
 20     }
 21     const int N=2e5+10;
 22     typedef long long LL;
 23     const LL INF=1e9;
 24     /******************tamplate*********************/
 25     int n,m,K,P,D,p[N],cnt,tot,root;
 26     struct node{
 27         int d[2],mn[2],mx[2],l,r,D,size;
 28         int& operator [] (int x){return d[x];}
 29         void read(){d[0]=getint();d[1]=getint();}
 30     }t[N],tmp;
 31     inline bool cmp(int x,int y){return t[x][D]<t[y][D];}
 32     #define L t[o].l
 33     #define R t[o].r
 34     #define mid (l+r>>1)
 35     void Push_up(int o){
 36         F(i,0,1){
 37             t[o].mn[i]=min(t[o][i],min(t[L].mn[i],t[R].mn[i]));
 38             t[o].mx[i]=max(t[o][i],max(t[L].mx[i],t[R].mx[i]));
 39         }
 40         t[o].size=t[L].size+t[R].size+1;
 41     }
 42     int build(int l,int r,int dir){
 43         D=dir;
 44         nth_element(p+l,p+mid,p+r+1,cmp);
 45         int o=p[mid];
 46         t[o].D=dir;
 47         L=l<mid?build(l,mid-1,dir^1):0;
 48         R=r>mid?build(mid+1,r,dir^1):0;
 49         Push_up(o);
 50         return o;
 51     }
 52     void dfs(int o){
 53         if (!o) return;
 54         dfs(L);
 55         p[++cnt]=o;
 56         dfs(R);
 57     }
 58     void rebuild(int &o){
 59         cnt=0;
 60         dfs(o);
 61         o=build(1,cnt,t[o].D);
 62     }
 63     void Insert(int &o,int dir){
 64         if (!o){
 65             o=++tot; t[o]=tmp;
 66             F(i,0,1) t[o].mn[i]=t[o].mx[i]=t[o][i];
 67             t[o].D=dir; t[o].size=1;
 68         }else{
 69             if (tmp[dir]<t[o][dir]){
 70                 Insert(L,dir^1); Push_up(o);
 71                 if ((double)t[L].size>(double)t[o].size*0.7) rebuild(o);
 72             }else{
 73                 Insert(R,dir^1); Push_up(o);
 74                 if ((double)t[R].size>(double)t[o].size*0.7) rebuild(o);
 75             }
 76         }
 77     }
 78     inline LL get(LL v){
 79         if (K==1) return abs(v);
 80         else return v*v;
 81     }
 82     inline double ANS(LL v){
 83         if (K==1) return v;
 84         else return sqrt(double(v));
 85     }
 86     inline LL getdis(int o){
 87         if (!o) return 1e16;
 88         LL ans=0;
 89         F(i,0,1){
 90             if (t[o].mn[i]>tmp[i]) ans+=get(t[o].mn[i]-tmp[i]);
 91             if (t[o].mx[i]<tmp[i]) ans+=get(tmp[i]-t[o].mx[i]);
 92         }
 93         return ans;
 94     }
 95     inline LL dis(int o){return get(t[o][0]-tmp[0])+get(t[o][1]-tmp[1]);}
 96     priority_queue<LL>Q;
 97     void query(int o){
 98         if (!o) return;
 99         LL dl=getdis(L),dr=getdis(R),d0=dis(o);
100         if (d0<Q.top()){Q.pop(); Q.push(d0);}
101         if (dl<dr){
102             if (dl<Q.top()) query(L);
103             if (dr<Q.top()) query(R);
104         }else{
105             if (dr<Q.top()) query(R);
106             if (dl<Q.top()) query(L);
107         }
108     }
109     double ans[5];
110     int main(){
111     #ifndef ONLINE_JUDGE
112         freopen("A1365.in","r",stdin);
113         freopen("A1365.out","w",stdout);
114     #endif
115         F(i,0,1) t[0].mn[i]=INF,t[0].mx[i]=-INF;
116         t[0].size=0;
117         tot=n=getint(); m=getint(); K=getint(); P=getint();
118         F(i,1,n) {t[i].read(); p[i]=i;}
119         root=build(1,n,1);
120         char cmd[5];
121         F(i,1,m){
122             scanf("%s",cmd);
123             tmp.read();
124             if (cmd[0]==‘Q‘){
125                 F(j,1,P) Q.push(1e16);
126                 query(root);
127                 D(j,P,1){
128                     ans[j]=ANS(Q.top());
129                     Q.pop();
130                 }
131                 F(j,1,P)
132                     printf("%.4f%c",ans[j],j==P ? ‘\n‘ : ‘ ‘);
133             }else{
134                 Insert(root,1);
135             }
136         }
137         return 0;
138     }

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次。

提交   试题讨论

时间: 2024-08-27 16:25:11

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

决策树 随机森林 adaboost

? 熵.互信息? 决策树学习算法 ? 信息增益 ? ID3.C4.5.CART? Bagging与随机森林? 提升 ? Adaboost/GDBT ? 熵.互信息 熵是对平均不确定性的度量. 平均互信息:得知特征Y的信息而使得对标签X的信息的不确定性减少的程度.描述随机变量之间的相似程度.(条件熵.相对熵:差异性) ? 决策树 决策树学习采用的是自顶向下的递归方法,有监督学习. 其基本思想是以信息熵为度量构造一棵熵值下降最快的树,到叶子节点处的熵值为零,此时每个叶节点中的实例都属于同一类. 建立

[Sdoi2013]森林

/* 平常这种题很常见的思路就是求出dfs序来,然后每次查询的时候就是在主席树上查询 x+y-lca-fa[lca] 的值就行了. 但是这个题要动态的给森林中加边,还是强制在线的,所以就需要考虑换一种方法来维护这个东西. 首先先dfs出每棵树来,然后对于link操作,可以启发式合并两个主席树.这里我们把主席树维护的dfs序变成维护每个点到根的这条路径.所里link的时候假设我们要把x合到y上,那么我们就边dfs x 这棵树,边用当前点的fa作为历史状态的root来更新当前点的root就行了.求l

Tsinsen A1333: 矩阵乘法(整体二分)

http://www.tsinsen.com/A1333 题意:-- 思路:和之前的第k小几乎一样,只不过把一维BIT换成二维BIT而已.注意二维BIT写法QAQ 1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <string> 6 #include <cmath> 7 #include &

bzoj 3669: [Noi2014]魔法森林

3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MB 动点spfa Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节点1,隐士则住在号节点N.小E需要通过这一片魔法森林,才能够拜访到隐士. 魔法森林中居住了一些妖怪.每当有人经过一条边的时候,这条边上的妖怪就会对其发起攻击.幸运的

树、二叉树、森林的转换

树转换为二叉树 (1)加线.在所有兄弟结点之间加一条连线. (2)去线.树中的每个结点,只保留它与第一个孩子结点的连线,删除它与其它孩子结点之间的连线. (3)层次调整.以树的根节点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明.(注意第一个孩子是结点的左孩子,兄弟转换过来的孩子是结点的右孩子) 森林转换为二叉树 (1)把每棵树转换为二叉树. (2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子,用线连接起来. 二叉树转换为树 是树转换为二

机器学习中的算法(1)-决策树模型组合之随机森林与GBDT

版权声明: 本文由LeftNotEasy发布于http://leftnoteasy.cnblogs.com, 本文可以被全部的转载或者部分使用,但请注明出处,如果有问题,请联系[email protected] 前言: 决策树这种算法有着很多良好的特性,比如说训练时间复杂度较低,预测的过程比较快速,模型容易展示(容易将得到的决策树做成图片展示出来)等.但是同时,单决策树又有一些不好的地方,比如说容易over-fitting,虽然有一些方法,如剪枝可以减少这种情况,但是还是不够的. 模型组合(比如

codecombat之边远地区的森林31-44关代码分享

codecombat中国游戏网址: http://www.codecombat.cn/ 所有代码为javascript代码分享 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 31.为援兵坚持住 // 食人魔正在爬悬崖 // 为集结民兵组织保护足够长时间的农民. loop { var flag = this.findFlag(); var enemy = this.findNearestEnemy(); if (flag) { // 捡旗子 this.pickUpFla

使用python实现森林算法方法步骤详解

本文和大家分享的是使用python实现森林算法相关内容,一起来看看吧,希望对大家学习python有所帮助. 算法描述 随机森林算法 决策树运行的每一步都涉及到对数据集中的最优**点(best split point)进行贪婪选择(greedy selection). 这个机制使得决策树在没有被剪枝的情况下易产生较高的方差.整合通过提取训练数据库中不同样本(某一问题的不同表现形式)构建的复合树及其生成的预测值能够稳定并降低这样的高方差.这种方法被称作引导**算法(bootstrap aggrega

Atitit 如何在水泥森林打猎 找到合适的公司

Atitit 如何在水泥森林打猎  找到合适的公司 1. 我们工作的本质就是打猎,万年前在草原森林里面打猎,现在在水泥森林里面打猎 2 1.1. 我们的本质职位只有一个,那就是猎人 2 1.2. 所有的商业活动本质上皆为打猎 2 2. 打猎就要有打猎的方法,打猎工具,还要对猎物进行识别..猎场搬迁 2 2.1. 猎物手册与通用知识 2 2.2. 打猎方法论,广博法优先于专一法 2 3. 猎物识别与锁定,了解猎物习性  公司的类型 3 3.1. 根据运营模式 ,运营驱动型:产品驱动型: 技术驱动型