题意:

  二维平面n个点 每次给出一个点询问距离第k小的点.

SOL:

  kdtree裸题,抄了一发别人的模板...二维割起来还是非常显然的.膜rzz的论文.

  不多说了吧....

Code:

  

/*==========================================================================
# Last modified: 2016-03-18 20:26
# Filename: 2626.cpp
# Description:
==========================================================================*/
#define me AcrossTheSky
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> #include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector> #define lowbit(x) (x)&(-x)
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define getlc(a) ch[(a)][0]
#define getrc(a) ch[(a)][1] #define maxn 100000
#define maxm 100000
#define pi 3.1415926535898
#define _e 2.718281828459
#define INF 1070000000
using namespace std;
typedef long long LL;
typedef unsigned long long uLL; template<class T> inline
void read(T& num) {
bool start=false,neg=false;
char c;
num=0; while((c=getchar())!=EOF) {
if(c=='-') start=neg=true;
else if(c>='0' && c<='9') {
start=true;
num=num*10+c-'0';
} else if(start) break;
}
if(neg) num=-num;
}
/*==================split line==================*/
int flag;
struct node{
int id;
LL x,y;
void in(int i){
read(x); read(y);
id=i;
}
bool operator<(const node& a)const{
if(!flag) return x<a.x;
return y<a.y;
}
}p[maxn];
LL sqr(LL x){return x*x;}
LL dist(node a,node b){return sqr(a.x-b.x)+sqr(a.y-b.y);} struct cpt{
LL dis;
int id;
bool operator<(const cpt &a)const{
if(dis!=a.dis) return dis>a.dis;
return id<a.id;
}
}; priority_queue<cpt> q; struct KD{
LL minv[2],maxv[2];
LL dis(node p){
LL x=max(abs(p.x-minv[0]),abs(p.x-maxv[0]));
LL y=max(abs(p.y-minv[1]),abs(p.y-maxv[1]));
return sqr(x)+sqr(y);
}
KD operator+(const KD &a){
KD c;
c.minv[0]=min(minv[0],a.minv[0]);
c.minv[1]=min(minv[1],a.minv[1]);
c.maxv[0]=max(maxv[0],a.maxv[0]);
c.maxv[1]=max(maxv[1],a.maxv[1]);
return c;
}
}; struct KDtree{
node p;KD c;
}tree[maxn];
int n,m,kth,ch[maxn][2],tot; int build(int l,int r,int k){
int x=++tot;
flag=k;
int mid=rs(l,r); nth_element(p+l,p+mid,p+r+1);
tree[x].p=p[mid];
tree[x].c.minv[0]=tree[x].c.maxv[0]=tree[x].p.x;
tree[x].c.minv[1]=tree[x].c.maxv[1]=tree[x].p.y;
if (l<=mid-1){
ch[x][0]=build(l,mid-1,k^1);
tree[x].c=tree[x].c+tree[ch[x][0]].c;
}
if (mid+1<=r){
ch[x][1]=build(mid+1,r,k^1);
tree[x].c=tree[x].c+tree[ch[x][1]].c;
}
return x;
}
void ask(int x,node a,int k){
cpt tmp=(cpt){dist(tree[x].p,a),tree[x].p.id};
int lc=ch[x][0],rc=ch[x][1];
flag=k;
if (q.size()<kth) q.push(tmp);
else if (tmp<q.top()){q.pop(); q.push(tmp);}
if (a<tree[x].p) swap(lc,rc);
if (lc && (q.size()<kth || tree[lc].c.dis(a)>=q.top().dis))
ask(lc,a,k^1);
if (rc && (q.size()<kth || tree[rc].c.dis(a)>=q.top().dis))
ask(rc,a,k^1);
}
int main(){
//freopen("a.in","r",stdin);
read(n);
FORP(i,1,n) p[i].in(i);
build(1,n,0);
int m; read(m);
FORP(i,1,m){
node a; a.in(i);
read(kth);
while (!q.empty()) q.pop();
ask(1,a,0);
printf("%d\n",q.top().id);
}
}

BZOJ 2626 & KDtree的更多相关文章

  1. BZOJ 2626 JZPFAR(KD-tree)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2626 题意:平面上有n个点.现在有m次询问,每次给定一个点(px, py)和一个整数k, ...

  2. BZOJ 2626: JZPFAR KDtree + 堆

    Code: #include<bits/stdc++.h> #define maxn 200000 #define inf 1000000000000000 #define mid ((l ...

  3. bzoj 2626: JZPFAR【KD-tree】

    和3053差不多,把pair first做成负数就可以用大根堆维护了 注意:要开long long:比较的时候因为编号也占权重所以要比较pair:编号不是mid!不是mid!是初始输入的那个编号!搞混 ...

  4. bzoj 2648 KD-tree

    稍微看了一下KD-tree的讲义,大概明白了它的原理,但是实现不出来... 所以无耻的抄了一下黄学长的... #include<iostream> #include<cstdio&g ...

  5. BZOJ 2648 kd-tree模板

    学习了一下kd-tree的基本写法 http://blog.csdn.net/jiangshibiao/article/details/34144829 配合 http://www.bilibili. ...

  6. BZOJ 4154 kd-tree dfs序 + 二维空间的区间(矩阵)更新单点查找

    一开始没思路 感觉像是一个树形dp 然而不会 然后看了一眼题解就明白了 一个点的子树 用dfs序表示肯定是一个连续的区间 并且由于有子树的距离限制 可以转化为一个深度的区间 于是每个点都会有一个在二维 ...

  7. BZOJ 4066 kd-tree 矩形询问求和

    第一次遇见强制在线的题目 每个操作都和前面的ans有关 所以不能直接离线做 在这个问题中 kdtree更像一个线段树在一维单点修改区间询问的拓展一样 如果区间被询问区间完全包含 就不用继续递归 插入时 ...

  8. bzoj 5355 kdtree 树链剖分

    https://www.lydsy.com/JudgeOnline/problem.php?id=5355 想在b站搜query on a tree系列不小心看到了这题 扑鼻而来的浓浓的OI风格的题面 ...

  9. 【24.91】【Tsinsen 1302】&【BZOJ 2626】JZPFAR

    时间限制:5.0s   内存限制:256.0MB   总提交次数:547   AC次数:137   平均分:40.31 将本题分享到:        查看未格式化的试题   提交   试题讨论 试题来 ...

随机推荐

  1. ReactNative环境配置

    参考链接 Windows系统安装React Native环境 windows下React Native Android 环境搭建 在Windows下搭建React Native Android开发环境 ...

  2. ajax实例1

    前台: function getDetail(index){ $.post("<%=request.getContextPath() %>/member/dbcenter!get ...

  3. IOS 开发,调用打电话,发短信,打开网址

    IOS 开发,调用打电话,发短信,打开网址   1.调用 自带mail [[UIApplication sharedApplication] openURL:[NSURL URLWithString: ...

  4. js 倒计时点击和当前时间

    <input id="btn" type="submit" value="确定" disabled="disabled&qu ...

  5. Asp.Net - 9.socket(聊天室)

    9.1 Socket相关概念 IP地址 每台联网的电脑都有一个唯一的IP地址. 长度32位,分为四段,每段8位,用十进制数字表示,每段范围 0 ~ 255 特殊IP:127.0.0.1 用户本地网卡测 ...

  6. Java学习笔记(十六)——Java RMI

    [前面的话] 最近过的好舒服,每天过的感觉很充实,一些生活和工作的技巧注意了就会发现,其实生活也是可以过的如此的有滋有味,满足现在的状况,并且感觉很幸福. 学习java RMI的原因是最近在使用dub ...

  7. Android屏幕旋转总结

    转自:http://www.myexception.cn/operating-system/1452058.html 1. ProjectConifg.mk中定义宏MTK_LCM_PHYSICAL_R ...

  8. UVA11542 Square(高斯消元 异或方程组)

    建立方程组消元,结果为2 ^(自由变元的个数) - 1 采用高斯消元求矩阵的秩 方法一: #include<cstdio> #include<iostream> #includ ...

  9. js注入

    1.JavaScript注入就是在浏览器地址栏中输入一段js代码,用来改变页面js变量.页面标签的内容. 使用Javascript注入,用户不需要关闭或保存网页就可以改变其内容,这是在浏览器的地址栏上 ...

  10. PHPCMS 多站点管理切换问题

    打开系统函数库global.func.php 可以看到获取站点ID的函数如下 /** * 获取当前的站点ID */ function get_siteid() { static $siteid; if ...