[BZOJ2850]巧克力王国

来源:互联网 发布:阿里云测试平台 编辑:程序博客网 时间:2024/04/29 03:58

原题地址

题目大意:二维平面里给出若干个点和若干个半平面,分别求在每个半平面内的点的点权和.

这个用Kdtree也很好维护.

AC code:

#include <cstdio>#include <algorithm>using namespace std;typedef long long ll;const ll K=2;const ll N=100010;ll n,m,tot,flg;struct Poi{    ll v;    ll d[K];    friend bool operator<(Poi x,Poi y){        return x.d[flg]<y.d[flg];    }}a[N];struct nod{    ll  sum;    ll  mxd[K],mnd[K];    Poi poi;    nod *ch[2];}pool[N];struct Kdtree{    nod *root;    Kdtree(){        build(&root,1,n,0);    }    void update(nod *p){        p->sum=p->poi.v;        if(p->ch[0]!=NULL) p->sum+=p->ch[0]->sum;        if(p->ch[1]!=NULL) p->sum+=p->ch[1]->sum;        for(ll i=0;i<K;i++){            p->mxd[i]=p->mnd[i]=p->poi.d[i];            if(p->ch[0]!=NULL){                p->mxd[i]=max(p->mxd[i],p->ch[0]->mxd[i]);                p->mnd[i]=min(p->mnd[i],p->ch[0]->mnd[i]);            }            if(p->ch[1]!=NULL){                p->mxd[i]=max(p->mxd[i],p->ch[1]->mxd[i]);                p->mnd[i]=min(p->mnd[i],p->ch[1]->mnd[i]);            }        }    }    void build(nod **p,ll L,ll R,ll flag){        if(L>R) return ;        *p=&pool[tot++];        if(L==R){            (*p)->poi=a[L];(*p)->sum=a[L].v;            for(ll i=0;i<K;i++) (*p)->mxd[i]=(*p)->mnd[i]=a[L].d[i];        }        ll M=(L+R)>>1;        flg=flag;        nth_element(a+L,a+M,a+R+1);        (*p)->poi=a[M];        build(&(*p)->ch[0],L,M-1,(flag+1)%K);        build(&(*p)->ch[1],M+1,R,(flag+1)%K);        update(*p);    }    ll query(nod *p,ll a,ll b,ll c){        if(a*p->mnd[0]+b*p->mnd[1]>=c&&a*p->mnd[0]+b*p->mxd[1]>=c&&           a*p->mxd[0]+b*p->mnd[1]>=c&&a*p->mxd[0]+b*p->mxd[1]>=c) return 0;        if(a*p->mnd[0]+b*p->mnd[1]<c&&a*p->mnd[0]+b*p->mxd[1]<c&&           a*p->mxd[0]+b*p->mnd[1]<c&&a*p->mxd[0]+b*p->mxd[1]<c) return p->sum;        ll v=(a*p->poi.d[0]+b*p->poi.d[1]<c)?p->poi.v:0,v0=0,v1=0;        if(p->ch[0]!=NULL) v0=query(p->ch[0],a,b,c);        if(p->ch[1]!=NULL) v1=query(p->ch[1],a,b,c);        return v+v0+v1;    }};int main(){    scanf("%lld%lld",&n,&m);    for(ll i=1;i<=n;i++) scanf("%lld%lld%lld",&a[i].d[0],&a[i].d[1],&a[i].v);    Kdtree T;    for(ll i=1;i<=m;i++){        ll a,b,c;        scanf("%lld%lld%lld",&a,&b,&c);        printf("%lld\n",T.query(T.root,a,b,c));    }    return 0;}
0 0
原创粉丝点击