【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 }
View Code

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

[Submit][Status][Discuss]
posted @ 2015-05-22 11:07  Tunix  阅读(331)  评论(0编辑  收藏  举报