BZOJ 2626: JZPFAR

Description

求平面第\(k\)远的点,\(n\leqslant 10^5\)

Solution

KD-Tree.

用一个堆统计答案即可...

Code

/**************************************************************
    Problem: 2626
    User: BeiYu
    Language: C++
    Result: Accepted
    Time:16080 ms
    Memory:4824 kb
****************************************************************/

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 100050;
const int M = 2;
const int K = 25;

inline int in(int x=0,char s=getchar(),int v=1) { while(s>‘9‘||s<‘0‘) v=s==‘-‘?-1:v,s=getchar();
    while(s>=‘0‘&&s<=‘9‘) x=x*10+s-‘0‘,s=getchar();return x*v; }

#define lc p[o].ch[0]
#define rc p[o].ch[1]
#define mid ((l+r)>>1)
#define sqr(x) ((x)*(x))

namespace KDTree {
    struct Node {
        int id,mi[M],mx[M],d[M],ch[2];
        Node() {
            id=ch[0]=ch[1]=0;
            for(int i=0;i<M;i++) mi[i]=mx[i]=d[i]=0;
        }
    }p[N];

    int D,cp,rt,k;Node qp;
    int cmp(const Node &a,const Node &b) { return a.d[D]<b.d[D]; }
    LL dis2(Node a,Node b) {
        LL d=0;
        for(int i=0;i<M;i++) d+=sqr((LL)a.d[i]-b.d[i]);
        return d;
    }
    double dis(Node a,Node b) { return sqrt(dis2(a,b)); }
    void Update(int o) {
        for(int i=0;i<M;i++) p[o].mx[i]=p[o].mi[i]=p[o].d[i];
        if(lc) for(int i=0;i<M;i++)
            p[o].mx[i]=max(p[o].mx[i],p[lc].mx[i]),p[o].mi[i]=min(p[o].mi[i],p[lc].mi[i]);
        if(rc) for(int i=0;i<M;i++)
            p[o].mx[i]=max(p[o].mx[i],p[rc].mx[i]),p[o].mi[i]=min(p[o].mi[i],p[rc].mi[i]);
    }
    void Build(int &o,int l,int r,int d) {
        D=d,o=mid,nth_element(p+l,p+o,p+r+1,cmp);
        if(l<mid) Build(lc,l,mid-1,(d+1)%M);
        if(r>mid) Build(rc,mid+1,r,(d+1)%M);
        Update(o);
    }
    LL S(int o) {
        LL res=0;
        for(int i=0;i<M;i++) res+=max(sqr((LL)p[o].mx[i]-qp.d[i]),sqr((LL)qp.d[i]-p[o].mi[i]));
        return res;
    }
    struct QNode { LL d2;int id; };
    bool operator < (const QNode &a,const QNode &b) { return a.d2==b.d2?a.id<b.id:a.d2>b.d2; }
    priority_queue<QNode> q;
    void Query(int o) {
        if(!o) return;
        LL d=dis2(p[o],qp),ll=lc?S(lc):-2,rr=rc?S(rc):-2;
        if((QNode) { d,p[o].id } < q.top()) q.pop(),q.push((QNode) { d,p[o].id });
        if(ll>rr) {
            if(ll>=q.top().d2) Query(lc);
            if(rr>=q.top().d2) Query(rc);
        } else {
            if(rr>=q.top().d2) Query(rc);
            if(ll>=q.top().d2) Query(lc);
        }
    }

    int Qur(int k,Node a) {
        for(;!q.empty();) q.pop();
        for(int i=0;i<k;i++) q.push((QNode) { -1,0 });
        qp=a;
        Query(rt);
        return q.top().id;
    }
};

using namespace KDTree;

int n,m;

int main() {
    cp=n=in();
    for(int i=1;i<=n;i++) {
        for(int j=0;j<M;j++) p[i].d[j]=in();
        p[i].id=i;
    }
    Build(rt=1,1,n,0);
    for(m=in();m--;) {
        Node a=Node();
        for(int j=0;j<M;j++) a.d[j]=in();
        int k=in();
        printf("%d\n",Qur(k,a));
    }
    return 0;
}

  

时间: 2024-11-02 23:25:51

BZOJ 2626: JZPFAR的相关文章

BZOJ 2626 JZPFAR(KD-tree)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2626 题意:平面上有n个点.现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号.如果有两个(或多个)点距离(px, py)相同,那么认为标号较小的点距离较大. 思路:对n个点做KDtree. 1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath

BZOJ 2626 JZPFAR K-D树

题目大意:给出平面上的一些点,求到一个点的最远的第k个点的标号. 思路:朴素的K-D树建树,然后在搜索的时候维护一个小跟堆,保留着最大的k个点,然后吧第k大的点作为基准点来判断是否更新其他的点. CODE: #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #de

BZOJ 2626 &amp; KDtree

题意: 二维平面n个点 每次给出一个点询问距离第k小的点. SOL: kdtree裸题,抄了一发别人的模板...二维割起来还是非常显然的.膜rzz的论文. 不多说了吧.... Code: /*========================================================================== # Last modified: 2016-03-18 20:26 # Filename: 2626.cpp # Description: =========

【BZOJ】【2626】JZPFAR

KD-Tree 0.0找第k大…… 裸KD-Tree……跟之前那道找最近的k个点大同小异 一开始理解错:第K大是第K远……不是第K近……(Tunix你个sb 感觉容易出错的是0号点= =边界情况需要仔细处理……根据题意而定的,比如这题就必须将0号点的距离设置成最近……比如-2……(因为我一开始向堆里加的占位点的距离是-1 1 /************************************************************** 2 Problem: 2626 3 User

bzoj 4199 &amp;&amp; NOI 2015 品酒大会

一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发"首席品酒家"和"首席猎手"两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainbow 调制了 nn 杯鸡尾酒.这 nn 杯鸡尾酒排成一行,其中第 ii 杯酒 (1≤i≤n1≤i≤n) 被贴上了一个标签 sisi,每个标签都是 2626 个小写英文字母之一.设 Str(l,r)Str(l,r) 表示第 ll 杯酒到第 rr 杯酒的 r?l+1

【醒目】【业界偷懒】【Public】BZOJ题目一句话题解整理

就当是复习一下自己做过的题,顺便提供一个简要题解给大家看. 做题时候实在想不出来看一下一句话题解,可以有一个提示的作用又不至于一下子知道了全部浪费了一道题吧.. 部分题目(如我A过得大部分奶牛题)是别人拿我的账号做的,不提供题解. 可能会漏掉很多做过的题..因为可能点页数不小心点错了什么的 UPD.本来想把那些没写过但是知道题解的也写了..但是写完这些已经累死了QAQ 已AC的题目(数学题均不提供分析过程,公式): 1000:A+B 1001:平面图最小割,转对偶图最短路 1002:矩阵树定理,

BZOJ 1013: [JSOI2008]球形空间产生器sphere

二次联通门 : BZOJ 1013: [JSOI2008]球形空间产生器sphere /* BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元 QAQ SB的我也能终于能秒题了啊 设球心的坐标为(x,y,z...) 那么就可以列n+1个方程,化化式子高斯消元即可 */ #include <cstdio> #include <iostream> #include <cstring> #define rg register #define Max

bzoj 3309 DZY Loves Math - 莫比乌斯反演 - 线性筛

对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0. 给定正整数a,b,求sigma(sigma(f(gcd(i,j)))) (i=1..a, j=1..b). Input 第一行一个数T,表示询问数. 接下来T行,每行两个数a,b,表示一个询问. Output 对于每一个询问,输出一行一个非负整数作为回答. Sample Input 4 7558588 9653114 6514903 445

【BZOJ】[HNOI2009]有趣的数列

[算法]Catalan数 [题解] 学了卡特兰数就会啦>_<! 因为奇偶各自递增,所以确定了奇偶各自的数字后排列唯一. 那么就是给2n个数分奇偶了,是不是有点像入栈出栈序呢. 将做偶数标为-1,做奇数标为+1,显然当偶数多于奇数时不合法,因为它压不住后面的奇数. 然后其实这种题目,打表就可知啦--QAQ 然后问题就是求1/(n+1)*C(2n,n)%p了,p不一定是素数. 参考bzoj礼物的解法. 看到网上清一色的素数筛+分解质因数解法,不解了好久,感觉写了假的礼物-- 后来觉得礼物的做法才比