关闭

BZOJ2850: 巧克力王国 kdtree

497人阅读 评论(0) 收藏 举报
分类:

题意:n个平面上的带权点,每次给出a,b,h,询问满足ax+by < h的点权和。
1 <= n, m <= 50000,其它10^9
kdtree划分矩形,显然若矩形四个顶点都在半平面内,则整个矩形在半平面内;四个顶点都在半平面外,则整个矩形在半平面外。
注意维护的是权值和,不是size

#include<cstdio>
#include<algorithm>
using std::nth_element;
typedef long long ll;
struct chok
{
    int p[2],v;
    chok(){}
    chok(int x,int y,int z):v(z){p[0]=x,p[1]=y;}
    inline int& operator [] (size_t x){return p[x];}
    inline const int& operator [] (size_t x) const {return p[x];}
};
inline int check(ll a,ll b,ll c,int x,int y)
{
    return a*x+b*y<c;
}
bool cmp;
inline bool fn(const chok &a,const chok &b)
{
    return a[cmp]<b[cmp];
}
inline void min(int &a,int b)
{
    if(b<a) a=b;
}
inline void max(int &a,int b)
{
    if(a<b) a=b;
}
struct node
{
    ll sum;
    chok p;
    int xn,yn,xm,ym;
    node *l,*r;
    node(const chok &p):sum(p.v),p(p),l(0),r(0),xn(p[0]),yn(p[1]),xm(p[0]),ym(p[1]){}
    inline void* operator new(size_t)
    {
        static unsigned char pool[50000*sizeof(node)];
        static node* s=(node*)pool;
        static size_t k=-1;
        return s+ ++k;
    }
    ll query(int a,int b,int c)
    {
        if(!this) return 0;
        int tot=check(a,b,c,xn,yn)+check(a,b,c,xn,ym)+check(a,b,c,xm,yn)+check(a,b,c,xm,ym);
        if(tot==4) return sum;
        if(!tot) return 0;
        ll res=0;
        if(check(a,b,c,p[0],p[1])) res+=p.v;
        return res+l->query(a,b,c)+r->query(a,b,c);
    }
    inline void up()
    {
        if(l) min(xn,l->xn),min(yn,l->yn),max(xm,l->xm),max(ym,l->ym),sum+=l->sum;
        if(r) min(xn,r->xn),min(yn,r->yn),max(xm,r->xm),max(ym,r->ym),sum+=r->sum;
    }
};
struct kdtree
{
    node *rt;
    node *build(chok* l,chok *r,bool k)
    {
        if(l==r) return 0;
        chok *mid=l+(r-l>>1);
        cmp=k;
        nth_element(l,mid,r,fn);
        node *kre=new node(*mid);
        kre->l=build(l,mid,!k);
        kre->r=build(mid+1,r,!k);
        kre->up();
        return kre;
    }
    kdtree(chok *a,int len):rt(build(a,a+len,0)){}
    inline ll query(int a,int b,int c)
    {
        return rt->query(a,b,c);
    }
};
int n,m;
chok choco[50000];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;++i)
    scanf("%d%d%d",&choco[i].p[0],&choco[i].p[1],&choco[i].v);
    kdtree tr(choco,n);
    for(int i=0;i<m;++i)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        printf("%lld\n",tr.query(a,b,c));
    }
    return 0;
}
1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:20145次
    • 积分:1096
    • 等级:
    • 排名:千里之外
    • 原创:90篇
    • 转载:0篇
    • 译文:0篇
    • 评论:18条
    博客专栏