zoukankan      html  css  js  c++  java
  • luogu P2093 [国家集训队]JZPFAR

    传送门

    要维护平面上点的信息,所以可以用KD-tree来维护,然后维护一个大小为(k)的堆,每次从根开始遍历,遇到一个点就看能不能作为前(k)远的点,也就是看能不能把堆中最近的点给替换掉.如果那个点在KD-tree上的控制区域中离要求的点的最远的点的距离比当前第(k)远距离小就不用访问了

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<map>
    #include<set>
    #define LL long long
    #define db double
    
    using namespace std;
    const int N=1e5+10;
    int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int nd;
    struct point
    {
        int d[2],i;
        bool operator < (const point &bb) const {return d[nd]!=bb.d[nd]?d[nd]<bb.d[nd]:i<bb.i;}
    }a[N],b[N],qwq;
    struct node
    {
        LL d;
        int i;
        bool operator < (const node &bb) const {return d!=bb.d?d>bb.d:i<bb.i;}
    };
    priority_queue<node> hp;
    int n,m,rt,ch[N][2],mx[N][2],my[N][2],szz;
    void bui(int &o,int l,int r,int nnd)
    {
        if(l>r) return;
        if(l==r)
        {
            o=b[l].i;
            mx[o][0]=mx[o][1]=a[o].d[0];
            my[o][0]=my[o][1]=a[o].d[1];
            return;
        }
        int mid=(l+r)>>1;
        nd=nnd;
        nth_element(b+l,b+mid,b+r+1);
        o=b[mid].i;
        mx[o][0]=mx[o][1]=a[o].d[0];
        my[o][0]=my[o][1]=a[o].d[1];
        bui(ch[o][0],l,mid-1,nnd^1);
        bui(ch[o][1],mid+1,r,nnd^1);
        mx[o][0]=min(mx[o][0],min(mx[ch[o][0]][0],mx[ch[o][1]][0]));
        mx[o][1]=max(mx[o][1],max(mx[ch[o][0]][1],mx[ch[o][1]][1]));
        my[o][0]=min(my[o][0],min(my[ch[o][0]][0],my[ch[o][1]][0]));
        my[o][1]=max(my[o][1],max(my[ch[o][0]][1],my[ch[o][1]][1]));
    }
    LL dis(point aa,point bb){return 1ll*(aa.d[0]-bb.d[0])*(aa.d[0]-bb.d[0])+1ll*(aa.d[1]-bb.d[1])*(aa.d[1]-bb.d[1]);}
    LL expt(int o)
    {
        if(!o) return -1;
        LL xx=max(mx[o][1]-qwq.d[0],qwq.d[0]-mx[o][0]),yy=max(my[o][1]-qwq.d[1],qwq.d[1]-my[o][0]);
        return xx*xx+yy*yy;
    }
    void wk(int o)
    {
        if(!o||expt(o)<hp.top().d) return;
        node nw=(node){dis(a[o],qwq),o};
        if(nw<hp.top()) hp.pop(),hp.push(nw);
        if(expt(ch[o][0])>expt(ch[o][1])) wk(ch[o][0]),wk(ch[o][1]);
        else wk(ch[o][1]),wk(ch[o][0]);
    }
    
    int main()
    {
        n=rd();
        for(int i=1;i<=n;++i) a[i].d[0]=rd(),a[i].d[1]=rd(),a[i].i=i,b[i]=a[i];
        mx[0][0]=my[0][0]=1<<30,mx[0][1]=my[0][1]=-(1<<30);
        bui(rt,1,n,0);
        m=rd();
        while(m--)
        {
            qwq.d[0]=rd(),qwq.d[1]=rd();
            int k=rd();
            while(!hp.empty()) hp.pop();
            while(k--) hp.push((node){-1,0});
            //szz=0; 
            wk(rt);
            node an=hp.top();
            printf("%d
    ",an.i);
        }
        return 0;
    }
    
  • 相关阅读:
    Picasso
    ImageLoader
    OkHttp3源码详解(二) 整体流程
    Android事件总线(三)otto用法全解析
    硅谷新闻9--图片三级缓存
    OkHttp3源码详解(一) Request类
    网络编程总结
    名称空间(Namespaces)(转)
    文件的增删改查
    生成器表达式和面向过程编程
  • 原文地址:https://www.cnblogs.com/smyjr/p/11054449.html
Copyright © 2011-2022 走看看