洛谷P4475 巧克力王國

洛谷P4475 巧克力王國ios

題目描述

巧克力王國裏的巧克力都是由牛奶和可可作成的。ui

可是並非每一塊巧克力都受王國人民的歡迎,由於你們都不喜歡過於甜的巧克力。spa

對於每一塊巧克力,咱們設 x 和 y 爲其牛奶和可可的含量。blog

因爲每一個人對於甜的程度都有本身的評判標準,因此每一個人都有兩個參數 a 和 b ,分別爲他本身爲牛奶和可可定義的權重, 所以牛奶和可可含量分別爲 x 和 y 的巧克力對於他的甜味程度即爲 ax+by。element

而每一個人又有一個甜味限度 c ,全部甜味程度大於等於 c 的巧克力他都沒法接受。get

每塊巧克力都有一個美味值 h 。it

如今咱們想知道對於每一個人,他所能接受的巧克力的美味值之和爲多少。io

輸入輸出格式

輸入格式:class

 

第一行兩個正整數 n 和 m ,分別表示巧克力個數和詢問個數。
接下來n行,每行三個整數 x , y , h ,含義如題目所示。
再接下來 m 行,每行三個整數 a , b , c,含義如題目所示。stream

輸出格式:

 

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

輸入輸出樣例

輸入樣例: 
3 3
1 2 5
3 1 4
2 2 1
2 1 6
1 3 5
1 3 7
輸出樣例: 
5
0
4

說明

對於100%的數據,$1<=n,m<=50000,-10^9<=a_i,b_i,x_i,y_i<=10^9$。


題解Here!

巧克力。。。不是凰麼???

莫名的病嬌既視感。。。

若是把那個$ax+by<c$當作半平面的話,這個成就成了平面上某一區域內全部點的點權和。

這種問題直接$K-D\ Tree$就好。

附代碼:

#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 50010
#define MAX (1LL<<60)
using namespace std;
int n,m,root;
bool sort_flag=false;
struct Point{
	long long x,y,z;
	friend bool operator <(const Point &p,const Point &q){
		if(sort_flag)return p.y<q.y;
		return p.x<q.x;
	}
}point[MAXN],now;
struct Tree{
	Point point;
	long long minx,miny,maxx,maxy,val,sum;
	int lson,rson;
}a[MAXN];
inline int read(){
	int date=0,w=1;char c=0;
	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
	return date*w;
}
void pushup(int rt){
	int lson=a[rt].lson,rson=a[rt].rson;
	a[rt].sum=a[lson].sum+a[rson].sum+a[rt].val;
	a[rt].maxx=max(a[rt].maxx,max(a[lson].maxx,a[rson].maxx));
	a[rt].maxy=max(a[rt].maxy,max(a[lson].maxy,a[rson].maxy));
	a[rt].minx=min(a[rt].minx,min(a[lson].minx,a[rson].minx));
	a[rt].miny=min(a[rt].miny,min(a[lson].miny,a[rson].miny));
}
void buildtree(int l,int r,int &rt,int flag){
	int mid=l+r>>1;
	rt=mid;
	sort_flag=flag;
	nth_element(point+l,point+mid,point+r+1);
	a[rt].point=point[mid];
	a[rt].val=point[mid].z;
	a[rt].maxx=a[rt].minx=point[mid].x;
	a[rt].maxy=a[rt].miny=point[mid].y;
	if(l<mid)buildtree(l,mid-1,a[rt].lson,flag^1);
	if(mid<r)buildtree(mid+1,r,a[rt].rson,flag^1);
	pushup(rt);
}
inline bool check(int rt){
	return ((a[rt].point.x*now.x+a[rt].point.y*now.y)<now.z);
}
inline long long max_dis(int rt){
	long long x,y;
	x=max(a[rt].minx*now.x,a[rt].maxx*now.x);
	y=max(a[rt].miny*now.y,a[rt].maxy*now.y);
	return x+y;
}
inline long long min_dis(int rt){
	long long x,y;
	x=min(a[rt].minx*now.x,a[rt].maxx*now.x);
	y=min(a[rt].miny*now.y,a[rt].maxy*now.y);
	return x+y;
}
long long query(int rt){
	long long dis=max_dis(rt);
	if(dis<now.z)return a[rt].sum;
	dis=min_dis(rt);
	if(dis>=now.z)return 0;
	long long ans=0;
	if(check(rt))ans+=a[rt].val;
	if(a[rt].lson)ans+=query(a[rt].lson);
	if(a[rt].rson)ans+=query(a[rt].rson);
	return ans;
}
void work(){
	while(m--){
		now.x=read();now.y=read();now.z=read();
		printf("%lld\n",query(root));
	}
}
void init(){
	n=read();m=read();
	a[0].maxx=a[0].maxy=-MAX;
	a[0].minx=a[0].miny=MAX;
	for(int i=1;i<=n;i++){point[i].x=read();point[i].y=read();point[i].z=read();}
	buildtree(1,n,root,0);
}
int main(){
	init();
	work();
    return 0;
}
相關文章
相關標籤/搜索