bzoj2850巧克力王国*

bzoj2850巧克力王国

题意:

n个巧克力,每个有牛奶含量,可可含量和美味值。m个人,每个有三个权值a,b,c,如果某个巧克力的牛奶含量*a+可可含量*b<c就可以接受。问每个人能接受的巧克力美味值之和。n,m≤50000。

题解:

对所有巧克力建kd树,树上节点除了维护子树横纵坐标最大最小值还要维护子树美味值之和。在查询时如果估价得出这个子树的牛奶含量最大值乘a+可可含量最大值*b小于c则整棵子树都能接受,否则只要该子树可能有机会存在可接受巧克力就遍历这棵子树。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define inc(i,j,k) for(int i=j;i<=k;i++)
 5 #define maxn 50010
 6 #define ll long long
 7 using namespace std;
 8
 9 inline ll read(){
10     char ch=getchar(); ll f=1,x=0;
11     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}
12     while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
13     return f*x;
14 }
15 int n,m,f,rt; ll ans;
16 struct p{int pos[2],v; bool operator < (const p &a)const{return pos[f]<a.pos[f];}}ps[maxn];
17 struct nd{p pos; int mx[2],mn[2],lc,rc; ll sm;}nds[maxn];
18 bool check(int a,int b,ll c,ll d,ll e){return c*a+d*b<e;}
19 void update(int x){
20     inc(i,0,1){
21         if(nds[x].lc)
22             nds[x].mx[i]=max(nds[x].mx[i],nds[nds[x].lc].mx[i]),
23             nds[x].mn[i]=min(nds[x].mn[i],nds[nds[x].lc].mn[i]);
24         if(nds[x].rc)
25             nds[x].mx[i]=max(nds[x].mx[i],nds[nds[x].rc].mx[i]),
26             nds[x].mn[i]=min(nds[x].mn[i],nds[nds[x].rc].mn[i]);
27     }
28     if(nds[x].lc)nds[x].sm+=nds[nds[x].lc].sm;
29     if(nds[x].rc)nds[x].sm+=nds[nds[x].rc].sm;
30 }
31 int build(int l,int r,int now){
32     f=now; int mid=(l+r)>>1; nth_element(ps+l,ps+mid,ps+r+1);
33     inc(i,0,1)nds[mid].mx[i]=nds[mid].mn[i]=ps[mid].pos[i]; nds[mid].sm=ps[mid].v; nds[mid].pos=ps[mid];
34     if(l<mid)nds[mid].lc=build(l,mid-1,now^1); if(mid<r)nds[mid].rc=build(mid+1,r,now^1);
35     update(mid); return mid;
36 }
37 int get(int x,ll a,ll b,ll c){
38     int q=0;
39     q+=check(nds[x].mx[0],nds[x].mx[1],a,b,c); q+=check(nds[x].mx[0],nds[x].mn[1],a,b,c);
40     q+=check(nds[x].mn[0],nds[x].mx[1],a,b,c); q+=check(nds[x].mn[0],nds[x].mn[1],a,b,c);
41     return q;
42 }
43 void query(int x,ll a,ll b,ll c){
44     if(check(nds[x].pos.pos[0],nds[x].pos.pos[1],a,b,c))ans+=nds[x].pos.v; int dl=0,dr=0;
45     if(nds[x].lc)dl=get(nds[x].lc,a,b,c); if(nds[x].rc)dr=get(nds[x].rc,a,b,c);
46     if(dl==4)ans+=nds[nds[x].lc].sm;else if(dl)query(nds[x].lc,a,b,c);
47     if(dr==4)ans+=nds[nds[x].rc].sm;else if(dr)query(nds[x].rc,a,b,c);
48 }
49 int main(){
50     n=read(); m=read(); inc(i,1,n)ps[i].pos[0]=read(),ps[i].pos[1]=read(),ps[i].v=read(); rt=build(1,n,0);
51     inc(i,1,m){
52         ll x=read(),y=read(),z=read(); ans=0; query(rt,x,y,z); printf("%lld\n",ans);
53     }
54     return 0;
55 }

20160906

时间: 2024-08-28 05:40:34

bzoj2850巧克力王国*的相关文章

【kd-tree】bzoj2850 巧克力王国

分四种情况讨论:a,b>=0 a,b<0 a>=0,b<0 a<0,b>=0 然后每次检验是否进入一个矩形框 或者 是否直接利用这个矩形框的答案 仅仅利用两个对角的坐标进行更新即可. #include<cstdio> #include<cmath> #include<algorithm> using namespace std; typedef long long ll; #define N 50001 #define INF 214

BZOJ2850 巧克力王国

题意:给定一堆点,每个点有权值,每次求在直线$Ax + By + C = 0$下的点的权值和 KD树维护一下二维区间内的点权和就好恩...建树复杂度$O(n * logn)$,单次查询时间$O(\sqrt{n})$ 1 /************************************************************** 2 Problem: 2850 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:155

【BZOJ2850】巧克力王国 KDtree

[BZOJ2850]巧克力王国 Description 巧克力王国里的巧克力都是由牛奶和可可做成的.但是并不是每一块巧克力都受王国人民的欢迎,因为大家都不喜 欢过于甜的巧克力.对于每一块巧克力,我们设x和y为其牛奶和可可的含量.由于每个人对于甜的程度都有自己的 评判标准,所以每个人都有两个参数a和b,分别为他自己为牛奶和可可定义的权重,因此牛奶和可可含量分别为x 和y的巧克力对于他的甜味程度即为ax + by.而每个人又有一个甜味限度c,所有甜味程度大于等于c的巧克力他都 无法接受.每块巧克力都

【bzoj2850】巧克力王国 KD-tree

题目描述 巧克力王国里的巧克力都是由牛奶和可可做成的.但是并不是每一块巧克力都受王国人民的欢迎,因为大家都不喜欢过于甜的巧克力.对于每一块巧克力,我们设x和y为其牛奶和可可的含量.由于每个人对于甜的程度都有自己的评判标准,所以每个人都有两个参数a和b,分别为他自己为牛奶和可可定义的权重,因此牛奶和可可含量分别为x和y的巧克力对于他的甜味程度即为ax + by.而每个人又有一个甜味限度c,所有甜味程度大于等于c的巧克力他都无法接受.每块巧克力都有一个美味值h.现在我们想知道对于每个人,他所能接受的

【BZOJ】【2850】【Violet 0】巧克力王国

KD-Tree 问平面内在某条直线下方的点的权值和 我一开始yy的是:直接判这个矩形最高的两个点(y坐标的最大值)是否在这条直线下方就可以了~即判$A*x+B*y<C$... 然而这并不对啊……因为你得分类讨论啊……不能直接判那个式子的啊…… 膜拜了hzwer的姿势:四个角都判,那么这样就避免了分类讨论……轻松+愉快 今天突然发现:KD-Tree是会Push_up叶子节点的,这点跟线段树不一样……QAQ怪不得以前模板那样写是错的…… 另外,鉴于上一题出了个讨厌的bug,我换了种姿势来push_u

P4475 巧克力王国(KDTree)

传送门 首先可以把约束条件看成一条直线,然后每个巧克力看成一个点,求给定区域内的点权和 用KDTree,每次判断一下当前矩形是否整个都在里面或都在外面,是的话直接返回,否则的话递归 注意,必须该矩形四个顶点都在里面或外面才能判断 //minamoto #include<bits/stdc++.h> #define R register #define ll long long #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i) #define f

[Luogu4475]巧克力王国

luogu 题意 平面上有\(n\)个点,每个点\((x_i,y_i)\),价值为\(w_i\).\(m\)次询问,每次给出\(a_i,b_i,c_i\)求满足\(a_ix+b_iy<c_i\)的点的总价值. \(n,m\le50000\) sol 正解貌似是\(O(n^{1.5}\log n)\)? 我只会\(kdt\)qaq 直接暴力就行了,每到一个结点判断是否可以直接返回(交集为空),全部算上(完全包含与查询范围),算是剪枝吧. code #include<cstdio> #inc

【题解】巧克力王国

题目链接 题目大意,求在给定要求内的数据之和. 挺简洁的,一样对于数据建树,维护一个\(sum\)美味度的和,上下界变成甜度,\(query\)时判断是不是满足客户甜度要求,如果四种搭配\((mi[0]->mx[1],mi[0]->mi[1],mx[0]->mi[1],mx[0]->mx[1])\) 均符合要求,则说明这整个区间答案都属于贡献,直接加\(sum\)即可. 否则,判断一波当前走到的点能不能贡献,然后分左右查询即可. #include<cstdio> #in

德芙背后刻骨铭心的痛

原文链接地址:http://bbs.fishc.com/home.php?mod=space&uid=9&do=blog&id=585 一直以来知道德芙"DOVE"是"DO YOU LOVE ME"的英文缩写,但却从不知道它背后的故事.今天闯进一个朋友的空间,读了这个故事后很受感动! 1919年的春天,卢森堡王室迎来了夏洛特公主继承王位,同时她又嫁给了波旁家庭的后裔费利克斯王子.做为王室后厨一个帮厨莱昂忙坏了,整天都在清理碗筷和盘子,双手裂开