【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 MBSubmit: 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
1 2 5
3 1 4
2 2 1
2 1 6
1 3 5
1 3 7
Sample Output
5
0
4
0
4
HINT
对于100% 的数据,1 <= n, m <= 50000,1 <= 10^9,-10^9 <= a, b, x, y <= 10^9。