KD-tree模板

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011056504/article/details/79111345

作为一个骗分神器,kdtree可以解决许多计算几何或者二维数点(代替二维数据结构)的问题
模板题:每个点(x,y,z)坐标(x,y),权值(z)
每个询问A,B,C,求满足 Ax+By<C 的权值和

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define N 501000
#define ll long long
#define INF 214748347
using namespace std;
ll n,m,tot=1,A,B,C,ans;
struct pt{
    ll x,y,z;
}a[N];
struct kdt{
    ll x,y,z,x1,y1,x2,y2,l,r,v;
}t[N];
bool cntx(pt a,pt b){return a.x<b.x;}
bool cnty(pt a,pt b){return a.y<b.y;}
void update(int v)
{
    t[v].x1=min(min(t[t[v].l].x1,t[t[v].r].x1),t[v].x);
    t[v].y1=min(min(t[t[v].l].y1,t[t[v].r].y1),t[v].y);
    t[v].x2=max(max(t[t[v].l].x2,t[t[v].r].x2),t[v].x);
    t[v].y2=max(max(t[t[v].l].y2,t[t[v].r].y2),t[v].y);
    t[v].v=t[v].v+t[t[v].l].v+t[t[v].r].v;
}
void build(int v,int l,int r,int tag)
{
    int mid=(l+r)/2;
    if(tag==0) nth_element(a+l,a+mid,a+r+1,cntx);
    else nth_element(a+l,a+mid,a+r+1,cnty);
    t[v].x=t[v].x1=t[v].x2=a[mid].x;t[v].y=t[v].y1=t[v].y2=a[mid].y;
    t[v].v=t[v].z=a[mid].z;
    if(l<mid) t[v].l=++tot,build(t[v].l,l,mid-1,tag^1);
    if(mid<r) t[v].r=++tot,build(t[v].r,mid+1,r,tag^1);
    update(v);
}
int get(ll x,ll y){return A*x+B*y<C?1:0;}
int sch(int v){return get(t[v].x1,t[v].y1)+get(t[v].x1,t[v].y2)+get(t[v].x2,t[v].y1)+get(t[v].x2,t[v].y2);}
void query(int v)
{
    if(get(t[v].x,t[v].y)) ans+=t[v].z;
    int jy;
    if(t[v].l)
    {
        jy=sch(t[v].l);
        if(jy==4) ans+=t[t[v].l].v;
        else if(jy) query(t[v].l);
    }
    if(t[v].r)
    {
        jy=sch(t[v].r);
        if(jy==4) ans+=t[t[v].r].v;
        else if(jy) query(t[v].r);
    }
}
int main()
{
    scanf("%lld%lld",&n,&m);
    fo(i,1,n) scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].z);
    t[0].x1=t[0].y1=INF,t[0].x2=t[0].y2=-INF,t[0].v=0;
    build(1,1,n,0);
    while(m--)
    {
        scanf("%lld%lld%lld",&A,&B,&C);
        ans=0;query(1);
        printf("%lld\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/u011056504/article/details/79111345