bzoj2850: 巧克力王国 kd-tree

来源:互联网 发布:微信外卖系统源码下载 编辑:程序博客网 时间:2024/04/29 20:19

裸kd-tree,注意估价函数的写法,每个点记个sum。

#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>using namespace std;#define ll long long#define maxn 60000int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}ll A,B,C,ans;int D,n,m,rt;struct node{    int d[2],mx[2],mn[2],v,l,r;    ll sum;    friend bool operator < (node aa,node bb)    {        return aa.d[D]<bb.d[D];    }}p[maxn];bool check(int x,int y){    return x*A+y*B<C;} struct tree{    node t[maxn];    int cal(int x){    int tmp=0;    tmp+=check(t[x].mn[0],t[x].mn[1]);    tmp+=check(t[x].mn[0],t[x].mx[1]);    tmp+=check(t[x].mx[0],t[x].mn[1]);    tmp+=check(t[x].mx[0],t[x].mx[1]);    return tmp;}    void update(int x)    {        for(int i=0;i<2;i++)        {            if(t[x].l)            {                t[x].mn[i]=min(t[x].mn[i],t[t[x].l].mn[i]);                t[x].mx[i]=max(t[x].mx[i],t[t[x].l].mx[i]);            }            if(t[x].r)            {                t[x].mn[i]=min(t[x].mn[i],t[t[x].r].mn[i]);                t[x].mx[i]=max(t[x].mx[i],t[t[x].r].mx[i]);            }        }        t[x].sum=t[x].v+t[t[x].l].sum+t[t[x].r].sum;    }    int build(int l,int r,int now)    {        D=now;        int mid=(l+r)>>1;        nth_element(p+l,p+mid+1,p+r+1);        t[mid]=p[mid];        for(int i=0;i<2;i++)            t[mid].mn[i]=t[mid].mx[i]=t[mid].d[i];        if(l<mid) t[mid].l=build(l,mid-1,now^1);        if(mid<r) t[mid].r=build(mid+1,r,now^1);        update(mid);        return mid;    }    void query(int x)    {        int l=t[x].l,r=t[x].r;        if(check(t[x].d[0],t[x].d[1])) ans+=t[x].v;        int tl=0,tr=0;        if(l) tl=cal(l);        if(r) tr=cal(r);        if(tl==4) ans+=t[l].sum;        else if(tl) query(l);        if(tr==4) ans+=t[r].sum;        else if(tr) query(r);    }}kd;int main(){    n=read();m=read();    for(int i=1;i<=n;i++)        p[i].d[0]=read(),p[i].d[1]=read(),p[i].v=read();    rt=kd.build(1,n,0);    while(m--)    {        A=read(),B=read(),C=read();        ans=0;        kd.query(rt);        printf("%lld\n",ans);    }    return 0;}


0 0
原创粉丝点击