• 洛谷P4475 巧克力王国


    洛谷P4475 巧克力王国

    题目描述

    巧克力王国里的巧克力都是由牛奶和可可做成的。

    但是并不是每一块巧克力都受王国人民的欢迎,因为大家都不喜欢过于甜的巧克力。

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

    由于每个人对于甜的程度都有自己的评判标准,所以每个人都有两个参数 a 和 b ,分别为他自己为牛奶和可可定义的权重, 因此牛奶和可可含量分别为 x 和 y 的巧克力对于他的甜味程度即为 ax+by。

    而每个人又有一个甜味限度 c ,所有甜味程度大于等于 c 的巧克力他都无法接受。

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

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

    输入输出格式

    输入格式:

    第一行两个正整数 n 和 m ,分别表示巧克力个数和询问个数。
    接下来n行,每行三个整数 x , y , h ,含义如题目所示。
    再接下来 m 行,每行三个整数 a , b , c,含义如题目所示。

    输出格式:

    输出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
    ",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;
    }
    
  • 相关阅读:
    FBWF和EWF的对比
    还原数据库备份文件时,关于“System.Data.SqlClient.SqlError:媒体集有2个媒体簇,但只提供了1个。必须提供所有成员”的处理方式
    C#基础(八)——C#数据类型的转换
    C#基础(七)——静态类与非静态类、静态成员的区别
    C#基础(六)——值类型与引用类型
    C#基础(五)——类中私有构造函数作用
    C#基础(四)——ref与out的区别
    C#基础(三)—重载与覆盖
    oracle exists和 not exists 的用法
    easyUI 常见问题点
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/10657936.html
Copyright © 2020-2023  润新知