bzoj 2626: JZPFAR【KD-tree】

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

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
const int N=100005,inf=1e9+7;
int n,m,rt,w;
priority_queue<pair<long long,int> >q;
map<pair<int,int>,int>mp;
struct qwe
{
    long long a[2];
    long long& operator [] (int x)
    {
        return a[x];
    }
    bool operator < (const qwe &b) const
    {
        return a[w]<b.a[w]||(a[w]==b.a[w]&&a[w^1]<b.a[w^1]);
    }
}a[N],b;
struct KD
{
    int ls,rs,l;
    qwe d,mn,mx;
}t[N<<2];
int read()
{
    int r=0,f=1;
    char p=getchar();
    while(p>'9'||p<'0')
    {
        if(p=='-')
            f=-1;
        p=getchar();
    }
    while(p>='0'&&p<='9')
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r*f;
}
void minn(long long &x,long long y)
{
    x>y?x=y:0;
}
void maxx(long long &x,long long y)
{
    x<y?x=y:0;
}
void ud(int ro)
{
    if(t[ro].ls)
    {
        for(int i=0;i<=1;i++)
            minn(t[ro].mn[i],t[t[ro].ls].mn[i]),maxx(t[ro].mx[i],t[t[ro].ls].mx[i]);
        t[ro].l=min(t[ro].l,t[t[ro].ls].l);
    }
    if(t[ro].rs)
    {
        for(int i=0;i<=1;i++)
            minn(t[ro].mn[i],t[t[ro].rs].mn[i]),maxx(t[ro].mx[i],t[t[ro].rs].mx[i]);
        t[ro].l=min(t[ro].l,t[t[ro].rs].l);
    }
}
int build(int l,int r,int f)
{
    if(l>r)
        return 0;
    int mid=(l+r)>>1;
    w=f;
    nth_element(a+l,a+mid,a+r+1);
    t[mid].l=mid;
    t[mid].mn=t[mid].mx=t[mid].d=a[mid];
    t[mid].ls=build(l,mid-1,f^1);
    t[mid].rs=build(mid+1,r,f^1);
    ud(mid);
    return mid;
}
long long dis(qwe a,qwe b)
{
    long long r=0;
    for(int i=0;i<=1;i++)
        r-=(a[i]-b[i])*(a[i]-b[i]);
    return r;
}
pair<long long,int> wk(int ro)
{
    if(!ro)
        return make_pair(1ll<<60,-1<<30);
    long long r=0;
    for(int i=0;i<=1;i++)
        r-=max((t[ro].mn[i]-b[i])*(t[ro].mn[i]-b[i]),(t[ro].mx[i]-b[i])*(t[ro].mx[i]-b[i]));
    return make_pair(r,t[ro].l);
}	
void ques(int ro)
{
    pair<long long,int> dm=make_pair(dis(t[ro].d,b),ro),dl=wk(t[ro].ls),dr=wk(t[ro].rs);
    if(dm<q.top())
        q.pop(),q.push(dm);
    if(dl<dr)
    {
        if(t[ro].ls&&dl<q.top())
            ques(t[ro].ls);
        if(t[ro].rs&&dr<q.top())
            ques(t[ro].rs);
    }
    else
    {
        if(t[ro].rs&&dr<q.top())
            ques(t[ro].rs);
        if(t[ro].ls&&dl<q.top())
            ques(t[ro].ls);
    }
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
        a[i][0]=read(),a[i][1]=read(),mp[make_pair(a[i][0],a[i][1])]=i;
    rt=build(1,n,0);
    m=read();
    while(m--)
    {
        b[0]=read(),b[1]=read();
        int s=read();
        while(!q.empty())
            q.pop();
        for(int i=1;i<=s;i++)
            q.push(make_pair(1ll<<60,-1<<30));
        ques(rt);
        printf("%d\n",mp[make_pair(t[q.top().second].d[0],t[q.top().second].d[1])]);
    }
    return 0;
}
posted @ 2018-12-11 09:06  lokiii  阅读(162)  评论(0编辑  收藏  举报