2850: 巧克力王国|K-D tree

K-D tree模板题
不会K-D tree可以戳http://blog.sina.com.cn/s/blog_6f611c300101bysf.html

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define ll long long
#define lowbit(x) (x&(-x))
#define N 50500
#define inf 1e9
using namespace std;
int sc()
{
    int i=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
    return i*f;
}
struct W{
    int d[2],mx[2],mn[2],l,r;
    ll  sum,v;
}t[N];
int n,m,D,root;
bool operator < (W a,W b){return a.d[D]<b.d[D];}
#define mid (l+r>>1)
#define L t[x].l
#define R t[x].r
void push_up(int x)
{
    for(int i=0;i<=1;i++)
    {
        t[x].mn[i]=min(t[x].d[i],min(t[L].mn[i],t[R].mn[i]));
        t[x].mx[i]=max(t[x].d[i],max(t[L].mx[i],t[R].mx[i]));
    }
    t[x].sum=t[L].sum+t[R].sum+t[x].v;
}
void build(int &x,int l,int r,int dir)
{
    x=mid;D=dir;
    nth_element(t+l,t+x,t+r+1);
    if(l<x)build(L,l,mid-1,dir^1);
    if(x<r)build(R,mid+1,r,dir^1);
    push_up(x);
}
int a,b,c;
bool check(int x,int y){return (ll)a*x+(ll)b*y<(ll)c;}
int  cal(W x)
{
    int ans=0;
    ans+=check(x.mn[0],x.mn[1]);
    ans+=check(x.mx[0],x.mn[1]);
    ans+=check(x.mn[0],x.mx[1]);
    ans+=check(x.mx[0],x.mx[1]);
    return ans;
}
ll query(int x)
{
    if(!x)return 0;
    ll ans=0;
    if(check(t[x].d[0],t[x].d[1]))ans+=t[x].v;
    int tl=L?cal(t[L]):0,tr=R?cal(t[R]):0;
    if(tl==4)ans+=t[L].sum;else if(tl)ans+=query(L);
    if(tr==4)ans+=t[R].sum;else if(tr)ans+=query(R);
    return ans;
}
int main()
{
    t[0].mn[0]=t[0].mn[1]=inf;
    t[0].mx[0]=t[0].mx[1]=-inf;
    t[0].sum=t[0].v=0;
    n=sc(),m=sc();
    for(int i=1;i<=n;i++)
        t[i].d[0]=sc(),t[i].d[1]=sc(),t[i].v=sc();
    build(root,1,n,1);
    for(int i=1;i<=m;i++)
    {
        a=sc(),b=sc(),c=sc();
        printf("%lld\n",query(root));
    }
    return 0;
}

你可能感兴趣的:(K-D-Tree)