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

KD-Tree



  问平面内在某条直线下方的点的权值和

  我一开始yy的是:直接判这个矩形最高的两个点(y坐标的最大值)是否在这条直线下方就可以了~即判$A*x+B*y<C$...

  然而这并不对啊……因为你得分类讨论啊……不能直接判那个式子的啊……

  膜拜了hzwer的姿势:四个角都判,那么这样就避免了分类讨论……轻松+愉快

今天突然发现:KD-Tree是会Push_up叶子节点的,这点跟线段树不一样……QAQ怪不得以前模板那样写是错的……

另外,鉴于上一题出了个讨厌的bug,我换了种姿势来push_up……味道好极了!

 1 /**************************************************************
 2     Problem: 2850
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:35044 ms
 7     Memory:3636 kb
 8 ****************************************************************/
 9
10 //BZOJ 2850
11 #include<cstdio>
12 #include<cstring>
13 #include<cstdlib>
14 #include<iostream>
15 #include<algorithm>
16 #define rep(i,n) for(int i=0;i<n;++i)
17 #define F(i,j,n) for(int i=j;i<=n;++i)
18 #define D(i,j,n) for(int i=j;i>=n;--i)
19 #define pb push_back
20 using namespace std;
21 typedef long long LL;
22 inline int getint(){
23     int r=1,v=0; char ch=getchar();
24     for(;!isdigit(ch);ch=getchar()) if (ch==‘-‘) r=-1;
25     for(; isdigit(ch);ch=getchar()) v=v*10-‘0‘+ch;
26     return r*v;
27 }
28 const int N=50010,INF=1e9;
29 /*******************template********************/
30 struct node{
31     int d[2],mn[2],mx[2],l,r;
32     LL sum,v;
33     int& operator [] (int x){return d[x];}
34     void read(){d[0]=getint();d[1]=getint();sum=v=getint();}
35 }t[N];
36 int n,m,D,root;
37 bool operator < (node a,node b){return a[D]<b[D];}
38
39 #define L t[o].l
40 #define R t[o].r
41 #define mid (l+r>>1)
42 void Push_up(int o){
43     F(i,0,1){
44         t[o].mn[i]=min(t[o][i],min(t[L].mn[i],t[R].mn[i]));
45         t[o].mx[i]=max(t[o][i],max(t[L].mx[i],t[R].mx[i]));
46     }
47     t[o].sum=t[L].sum+t[R].sum+t[o].v;
48 }
49
50 inline int build(int l,int r,int dir){
51     D=dir;
52     nth_element(t+l,t+mid,t+r+1);
53     int o=mid;
54     L=l<mid ? build(l,mid-1,dir^1) : 0;
55     R=mid<r ? build(mid+1,r,dir^1) : 0;
56     Push_up(o);
57     return o;
58 }
59 int a,b,c;
60 inline bool check(int x,int y){return (LL)a*x+(LL)b*y<(LL)c;}
61 inline int calc(node o){
62     int ans=0;
63     ans+=check(o.mn[0],o.mn[1]);
64     ans+=check(o.mx[0],o.mn[1]);
65     ans+=check(o.mn[0],o.mx[1]);
66     ans+=check(o.mx[0],o.mx[1]);
67     return ans;
68 }
69 inline LL query(int o){
70     if (!o) return 0;
71     LL ans=0;
72     if (check(t[o][0],t[o][1])) ans+=t[o].v;
73     int tl=L ? calc(t[L]) : 0,tr=R ? calc(t[R]) : 0;
74     if (tl==4) ans+=t[L].sum;
75     else if (tl) ans+=query(L);
76     if (tr==4) ans+=t[R].sum;
77     else if (tr) ans+=query(R);
78     return ans;
79 }
80
81 int main(){
82 #ifndef ONLINE_JUDGE
83     freopen("2850.in","r",stdin);
84     freopen("2850.out","w",stdout);
85 #endif
86     F(i,0,1) t[0].mn[i]=INF,t[0].mx[i]=-INF;
87     t[0].sum=t[0].v=0;
88
89     n=getint(); m=getint();
90     F(i,1,n) t[i].read();
91     root=build(1,n,1);
92     F(i,1,m){
93         a=getint(); b=getint(); c=getint();
94         printf("%lld\n",query(root));
95     }
96     return 0;
97 }

2850: 巧克力王国

Time Limit: 60 Sec  Memory Limit: 512 MB
Submit: 131  Solved: 54
[Submit][Status][Discuss]

Description

巧克力王国里的巧克力都是由牛奶和可可做成的。但是并不是每一块巧克力

都受王国人民的欢迎,因为大家都不喜欢过于甜的巧克力。

对于每一块巧克力,我们设x和y为其牛奶和可可的含量。

由于每个人对于甜的程度都有自己的评判标准,所以每个人都有两个参数a和

b,分别为他自己为牛奶和可可定义的权重,因此牛奶和可可含量分别为x和y

的巧克力对于他的甜味程度即为ax + by。而每个人又有一个甜味限度c,所有

甜味程度大于等于c的巧克力他都无法接受。

每块巧克力都有一个美味值h。

现在我们想知道对于每个人,他所能接受的巧克力的美味值之和为多少。

Input

第一行两个正整数n和m,分别表示巧克力个数和询问个数。

接下来n行,每行三个整数x,y,h,含义如题目所示。

再接下来m行,每行三个整数a,b,c,含义如题目所示。

Output

输出m行,其中第i行表示第i个人所能接受的巧克力的美味值之和。

Sample Input

3 3

1 2 5

3 1 4

2 2 1

2 1 6

1 3 5

1 3 7

Sample Output

5

0

4

HINT

对于100% 的数据,1 <= n, m <= 50000,1 <= 10^9,-10^9 <= a, b, x, y <= 10^9。

Source

Violet 0

[Submit][Status][Discuss]

时间: 2024-11-19 00:49:43

【BZOJ】【2850】【Violet 0】巧克力王国的相关文章

二分+最短路判定 BZOJ 2709: [Violet 1]迷宫花园

BZOJ 2709: [Violet 1]迷宫花园 Sample Input 5 10.28 9 9 ######### # # # # # # # #S# # ##### # # ## # # # ### ### ##E # ######### 4.67 9 9 ######### # ## ## ### #S# # # # E ## # # ##### # ## ### # ##### # # # # ######### 39.06 9 9 ######### # # # # # # # #

【BZOJ2850】巧克力王国 KDtree

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

bzoj2850巧克力王国*

bzoj2850巧克力王国 题意: n个巧克力,每个有牛奶含量,可可含量和美味值.m个人,每个有三个权值a,b,c,如果某个巧克力的牛奶含量*a+可可含量*b<c就可以接受.问每个人能接受的巧克力美味值之和.n,m≤50000. 题解: 对所有巧克力建kd树,树上节点除了维护子树横纵坐标最大最小值还要维护子树美味值之和.在查询时如果估价得出这个子树的牛奶含量最大值乘a+可可含量最大值*b小于c则整棵子树都能接受,否则只要该子树可能有机会存在可接受巧克力就遍历这棵子树. 代码: 1 #includ

【bzoj2850】巧克力王国 KD-tree

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

BZOJ 2725: [Violet 6]故乡的梦 最短路+线段树

2725: [Violet 6]故乡的梦 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 678  Solved: 204[Submit][Status][Discuss] Description Input Output Sample Input 6 7 1 2 1 2 3 1 3 4 2 4 5 1 5 6 1 1 3 3 4 6 3 1 6 4 1 2 1 3 4 3 6 5 Sample Output 7 6 Infinity 7 HINT

bzoj 2850

比较基础的KD树.每个节点维护一个BOX,包含包含当当前子树的点的最小矩形,以及点权和,然后用“整个矩形都在直线的一侧”和“整个矩形都不在直线的一侧”剪枝. 1 /************************************************************** 2 Problem: 2850 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:27240 ms 7 Memory:3740 kb 8 ****

BZOJ 2724: [Violet 6]蒲公英

2724: [Violet 6]蒲公英 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1633  Solved: 563[Submit][Status][Discuss] Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 Output Sample Input 6 3 1 2 3 2 1 2 1 5 3 6 1 5 Sample Outp

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

BZOJ 2718: [Violet 4]毕业旅行( 最长反链 )

一不小心速度就成了#1.... 这道题显然是求最长反链, 最长反链=最小链覆盖.最小链覆盖就是先做一次floyd传递闭包, 再求最小路径覆盖. 最小路径覆盖=N - 二分图最大匹配. 所以把所有点拆成x,y两个, 然后存在edge(u,v)就连ux->vy. 然后跑匈牙利即可. ------------------------------------------------------------------ #include<bits/stdc++.h> using namespace