• [Luogu4475]巧克力王国


    luogu

    题意

    平面上有(n)个点,每个点((x_i,y_i)),价值为(w_i)(m)次询问,每次给出(a_i,b_i,c_i)求满足(a_ix+b_iy<c_i)的点的总价值。
    (n,mle50000)

    sol

    正解貌似是(O(n^{1.5}log n))
    我只会(kdt)qaq
    直接暴力就行了,每到一个结点判断是否可以直接返回(交集为空),全部算上(完全包含与查询范围),算是剪枝吧。

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int gi(){
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    #define ll long long
    #define ls t[o].ch[0]
    #define rs t[o].ch[1]
    #define cmin(a,b) (a>b?a=b:a)
    #define cmax(a,b) (a<b?a=b:a)
    const int N = 5e4+5;
    int n,m,D,root;ll ans;
    struct node{
    	int d[2],key;
    	bool operator < (const node &b) const
    		{return d[D]<b.d[D];}
    }a[N];
    struct kdtree{int d[2],Min[2],Max[2],ch[2];ll sum;}t[N];
    void mt(int x,int y){
    	cmin(t[x].Min[0],t[y].Min[0]);cmax(t[x].Max[0],t[y].Max[0]);
    	cmin(t[x].Min[1],t[y].Min[1]);cmax(t[x].Max[1],t[y].Max[1]);
    	t[x].sum+=t[y].sum;
    }
    int build(int l,int r,int d){
    	D=d;int o=l+r>>1;
    	nth_element(a+l,a+o,a+r+1);
    	t[o].d[0]=t[o].Min[0]=t[o].Max[0]=a[o].d[0];
    	t[o].d[1]=t[o].Min[1]=t[o].Max[1]=a[o].d[1];
    	t[o].sum=a[o].key;
    	if (l<o) ls=build(l,o-1,d^1),mt(o,ls);
    	if (o<r) rs=build(o+1,r,d^1),mt(o,rs);
    	return o;
    }
    inline bool empty(int o,int x,int y,int z){
    	if (1ll*t[o].Min[0]*x+1ll*t[o].Min[1]*y<z) return 0;
    	if (1ll*t[o].Min[0]*x+1ll*t[o].Max[1]*y<z) return 0;
    	if (1ll*t[o].Max[0]*x+1ll*t[o].Min[1]*y<z) return 0;
    	if (1ll*t[o].Max[0]*x+1ll*t[o].Max[1]*y<z) return 0;
    	return 1;
    }
    inline bool whole(int o,int x,int y,int z){
    	if (1ll*t[o].Min[0]*x+1ll*t[o].Min[1]*y>=z) return 0;
    	if (1ll*t[o].Min[0]*x+1ll*t[o].Max[1]*y>=z) return 0;
    	if (1ll*t[o].Max[0]*x+1ll*t[o].Min[1]*y>=z) return 0;
    	if (1ll*t[o].Max[0]*x+1ll*t[o].Max[1]*y>=z) return 0;
    	return 1;
    }
    inline bool in(int o,int x,int y,int z){
    	return 1ll*t[o].d[0]*x+1ll*t[o].d[1]*y<z;
    }
    void query(int o,int x,int y,int z){
    	if (empty(o,x,y,z)) return;
    	if (whole(o,x,y,z)) {ans+=t[o].sum;return;}
    	if (in(o,x,y,z)) ans+=a[o].key;
    	if (ls) query(ls,x,y,z);if (rs) query(rs,x,y,z);
    }
    int main(){
    	n=gi();m=gi();
    	for (int i=1;i<=n;++i) a[i]=(node){gi(),gi(),gi()};
    	root=build(1,n,0);
    	while (m--){
    		int x=gi(),y=gi(),z=gi();ans=0;
    		query(root,x,y,z);printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    多种 网页文本编辑器 分析
    struts2 令牌 实现源代码 JSP
    ibatis 数据库时间 插入数据
    Eclipse/Myeclipse生成serialVersionUID方法
    SSM框架整合遇到的问题
    搭建Elasticsearch5.6.8 分布式集群
    使用SuperWebSocket 构建实时 Web 应用
    HAPROXY
    .NET面试题系列(二)GC
    MongoDB-3.4集群搭建:分片
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9077973.html
Copyright © 2020-2023  润新知