BZOJ2850: 巧克力王国 kdtree

原创 2017年01月03日 15:15:46

题意: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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

BZOJ 2850 巧克力王国

KDtree+思路

【BZOJ2850】巧克力王国

Description巧克力王国里的巧克力都是由牛奶和可可做成的。但是并不是每一块巧克力都受王国人民的欢迎,因为大家都不喜 欢过于甜的巧克力。对于每一块巧克力,我们设x和y为其牛奶和可可的含量。由于...

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

K-D tree模板题 不会K-D tree可以戳http://blog.sina.com.cn/s/blog_6f611c300101bysf.html#include #include #inc...
  • ws_yzy
  • ws_yzy
  • 2016年03月03日 09:01
  • 554

KD Tree 新知选作(BZOJ 2850)

什么是KDrree一些优质入门文章在这里附上两篇笔者学习kdtree的思路和详细实现思想的优质文章:思路篇传送门 详细篇传送门同时鸣谢为笔者耐心讲解kdtree的神犇:mima_reincarnat...

【BZOJ】【P2648&P2716】【SJY摆棋子】【天使玩偶】【题解】【kdtree】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2648 http://www.lydsy.com/JudgeOnline/problem.ph...

【BZOJ1941】【SDOI2010】Hide and Seek、KDTree【数组版】 模板、

KDT数组版模板!数组版数组版
  • Vmurder
  • Vmurder
  • 2014年12月25日 20:23
  • 1072

BZOJ 2716 [Violet 3]天使玩偶 KDtree

以下引用自“‎Alboi_真神名曰驴蛋蛋”对于一颗普通的K-D树,让K-D树上每个节点记录它这颗子树的大小(size)和这颗子树所能延伸到的最大横坐标,最小横坐标,最大纵坐标,最小纵坐标......就...

KDtree(bzoj2648)

我的第一篇博客

【BZOJ】【P3053】【The Closest M Points】【题解】【kdtree】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3053 既然 @nilihan1999 神犇一直不更新...

bzoj 2468 kdtree

Description 这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:BZOJ2850: 巧克力王国 kdtree
举报原因:
原因补充:

(最多只允许输入30个字)