BZOJ3053 - The Closest M Points

原题链接

Description

给出K(K5)维空间中的n(n5×104)个点,然后t(t104)次询问距离某个坐标m(m10)近的点,将这m个点由近到远输出。坐标的绝对值不超过104

Solution

跟普通的k-d树差不多,就是要开一个容量为m的大根堆,初始堆里有minf,比较时如果比堆顶小就插入,如果到区间的距离都比堆顶要大就不需要做了。

Code

这个代码目前RE!又是对拍全过然后GG…

//The Closest M Points
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
inline char gc()
{
    static char now[1<<16],*S,*T;
    if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;}
    return *S++;
}
inline int read()
{
    int x=0,f=1; char ch=gc();
    while((ch<'0'||'9'<ch)&&ch!=EOF) {if(ch=='-') f=-1; ch=gc();}
    while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
    return x*f;
}
int const N=5e4+10;
int const INF=0x7FFFFFFF;
int n,K;
#define ch1 ch[p][0]
#define ch2 ch[p][1]
int rt,ch[N][2];
struct point{int c[5];} pt[N];
struct zone{int c1[5],c2[5];} zn[N];
int D; bool cmpPt(point x,point y) {return x.c[D]<y.c[D];}
void update(int p)
{
    for(int k=0;k<K;k++)
    {
        zn[p].c1[k]=min(pt[p].c[k],min(zn[ch1].c1[k],zn[ch2].c1[k]));
        zn[p].c2[k]=max(pt[p].c[k],max(zn[ch1].c2[k],zn[ch2].c2[k]));
    }
}
void build(int &p,int L,int R,int k0)
{
    p=L+R>>1; D=k0;
    nth_element(pt+L,pt+p,pt+R+1,cmpPt);
    if(L<p) build(ch[p][0],L,p-1,(k0+1)%K);
    if(p<R) build(ch[p][1],p+1,R,(k0+1)%K);
    update(p);
}
point A;
int dst(point B)
{
    int res=0; if(B.c[0]==INF) return INF;
    for(int k=0;k<K;k++) res+=(A.c[k]-B.c[k])*(A.c[k]-B.c[k]);
    return res;
}
int dst(zone z)
{
    int res=0;
    for(int k=0;k<K;k++)
        if(A.c[k]<z.c1[k]) res+=(z.c1[k]-A.c[k])*(z.c1[k]-A.c[k]);
        else if(z.c2[k]<A.c[k]) res+=(A.c[k]-z.c2[k])*(A.c[k]-z.c2[k]);
    return res;
}
#define pInt pair<int,int>
priority_queue< pInt,vector<pInt>,less<pInt> > q;
void query(int p)
{
    if(dst(pt[p])<dst(pt[q.top().second])) q.pop(),q.push(make_pair(dst(pt[p]),p));
    int p0=q.top().second;
    if(ch1&&dst(zn[ch1])<dst(pt[p0])) query(ch1);
    if(ch2&&dst(zn[ch2])<dst(pt[p0])) query(ch2);
}
int ans[20];
int main()
{
    while(true)
    {

    n=read(),K=read(); if(n==0) break;
    for(int k=0;k<K;k++) pt[0].c[k]=INF,zn[0].c1[k]=INF,zn[0].c2[k]=-INF;
    for(int i=1;i<=n;i++)
        for(int k=0;k<K;k++) pt[i].c[k]=read();
    build(rt,1,n,0);
    int t=read();
    while(t--)
    {
        for(int k=0;k<K;k++) A.c[k]=read();
        int m=read(); for(int i=1;i<=m;i++) q.push(make_pair(INF,0));
        query(rt);
        printf("the closest %d points are:\n",m);
        for(int i=m;i>=1;i--) ans[i]=q.top().second,q.pop();
        for(int i=1;i<=m;i++)
        {
            for(int k=0;k<K;k++) printf("%d ",pt[ans[i]].c[k]);
            printf("\n");
        }
        while(!q.empty()) q.pop();
    }

    }
    return 0;
}

P.S.

我好菜啊…

转载于:https://www.cnblogs.com/VisJiao/p/8485745.html

资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 在 Linux 系统中,查找域名或主机名对应的 IP 地址是网络管理中的一项基础且关键任务,对于排查网络故障、调试网络问题以及监控网络服务是否正常运行等场景都非常重要。本文将介绍五种在 Linux 终端查询域名 IP 地址的方法。 首先,dig 命令(全称 Domain Information Groper)是一个功能强大的 DNS 查询工具,能够向 DNS 服务器发送查询请求并获取详细的响应信息。如果需要查询单个域名的 IP 地址,可以使用命令 dig 2daygeek.com +short 。此外,还可以通过编写 bash 脚本,将包含域名的文本文件中的域名逐个读取,然后利用 dig 命令进行查询,从而实现批量查询域名 IP 地址的功能。 其次,host 命令是一个简单易用的 DNS 查询工具,主要用于将域名解析为 IP 地址。要获取某个域名的 IP 地址,直接使用 host 2daygeek.com 即可。如果只想显示 IP 地址部分,可以通过管道结合 grep 和 sed 命令来实现,例如:host 2daygeek.com | grep "has address" | sed s/has address/-/g 。 再者,nslookup 命令也是一种常用的 DNS 查询工具,它支持交互式查询 DNS 信息。通过 nslookup 2daygeek.com 可以查询域名的 IP 地址。若要以非交互式的方式只显示 IP 地址,可以使用命令 nslookup 2daygeek.com | awk /^Address:/ {print $2} 。 另外,fping 命令与传统的 ping 命令不同,它不会直接进行 DNS 查询,而是通过发送 ICMP Echo Request(pi
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值