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
1 <= n, m <= 50000,1 <= 10^9,-10^9 <= a, b, x, y <= 10^9。
这题做法真的挺暴力的 把所有的巧克力的可可和牛奶看做二维平面中的点的x与y坐标 然后以此建立kd tree 怎么个暴力呢?根据之前做的题,我已经估计出来某个叶子结点的区间了 那么,我只需要看看这个我查询的区间是否可以全部覆盖我当前叶子结点所有点的最大区间 我就直接把这个节点代表的所有的点的权值和都累加 如果我这个区间的一个端点可能出现在我查询的区间中 那么我就递归下去去做这个区间
#include<cmath>
#include<cstdio>
#include<algorithm>
#define inf 0x3f3f3f3f
#define N 110000
#define ll long long
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if(T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=gc();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();}
return x*f;
}
struct node{
int left,right,x,y,minx,maxx,miny,maxy,v;ll sum;
}tree[N];
int D,num,n,m,root;ll ans=0;
struct node1{
ll x,y,v;
friend bool operator<(node1 a,node1 b){
if (!D) return a.x<b.x;return a.y<b.y;
}
}P,point[N>>1];
inline void update(int x){
int l=tree[x].left,r=tree[x].right;
tree[x].sum+=tree[l].sum+tree[r].sum;
tree[x].minx=min(tree[x].minx,min(tree[l].minx,tree[r].minx));
tree[x].miny=min(tree[x].miny,min(tree[l].miny,tree[r].miny));
tree[x].maxx=max(tree[x].maxx,max(tree[l].maxx,tree[r].maxx));
tree[x].maxy=max(tree[x].maxy,max(tree[l].maxy,tree[r].maxy));
}
inline void build(int &x,int l,int r,int dim){
x=++num;D=dim;int mid=l+r>>1;nth_element(point+l,point+mid,point+r+1);
tree[x].sum=tree[x].v=point[mid].v;tree[x].x=point[mid].x;tree[x].y=point[mid].y;
tree[x].minx=tree[x].maxx=point[mid].x;tree[x].miny=tree[x].maxy=point[mid].y;
if (l<mid) build(tree[x].left,l,mid-1,dim^1);
if (r>mid) build(tree[x].right,mid+1,r,dim^1);update(x);
}
inline bool judge1(int x){
if (P.x*tree[x].minx+P.y*tree[x].miny>=P.v) return 0;
if (P.x*tree[x].minx+P.y*tree[x].maxy>=P.v) return 0;
if (P.x*tree[x].maxx+P.y*tree[x].miny>=P.v) return 0;
if (P.x*tree[x].maxx+P.y*tree[x].maxy>=P.v) return 0;
return 1;
}
inline bool judge2(int x){
if (P.x*tree[x].minx+P.y*tree[x].miny<P.v) return 1;
if (P.x*tree[x].minx+P.y*tree[x].maxy<P.v) return 1;
if (P.x*tree[x].maxx+P.y*tree[x].miny<P.v) return 1;
if (P.x*tree[x].maxx+P.y*tree[x].maxy<P.v) return 1;
return 0;
}
inline void query(int x,int dim){
if(P.x*tree[x].x+P.y*tree[x].y<P.v) ans+=tree[x].v;
if (tree[x].left&&judge1(tree[x].left)) ans+=tree[tree[x].left].sum;
else if (tree[x].left&&judge2(tree[x].left)) query(tree[x].left,dim^1);
if (tree[x].right&&judge1(tree[x].right)) ans+=tree[tree[x].right].sum;
else if (tree[x].right&&judge2(tree[x].right)) query(tree[x].right,dim^1);
}
int main(){
freopen("bzoj2850.in","r",stdin);
n=read();m=read();tree[0].minx=tree[0].miny=inf;tree[0].maxx=tree[0].maxy=-inf;
for (int i=1;i<=n;++i) point[i].x=read(),point[i].y=read(),point[i].v=read();
build(root,1,n,0);
for (int i=1;i<=m;++i){
P.x=read();P.y=read();P.v=read();
ans=0;query(root,0);printf("%lld\n",ans);
}
return 0;
}