zoukankan      html  css  js  c++  java
  • 【题解】巧克力王国

    题目链接

    题目大意,求在给定要求内的数据之和。

    挺简洁的,一样对于数据建树,维护一个(sum)美味度的和,上下界变成甜度,(query)时判断是不是满足客户甜度要求,如果四种搭配((mi[0]->mx[1],mi[0]->mi[1],mx[0]->mi[1],mx[0]->mx[1]))
    均符合要求,则说明这整个区间答案都属于贡献,直接加(sum)即可。

    否则,判断一波当前走到的点能不能贡献,然后分左右查询即可。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define int long long
    const int MAXN=5e5+10;
    //挺简单的基础K-D_TREE 
    struct pt{
    	int x[2],cnt;
    }p[MAXN];
    struct node{
    	int siz,mi[2],mx[2],sum;
    	//sum维护区间和 
    	pt c;
    }tr[MAXN];
    int n,m,rt,tot,D;
    int ls[MAXN],rs[MAXN];
    int operator<(pt a,pt b){return a.x[D]<b.x[D];}
    inline void pushup(int x){
    	int l=ls[x],r=rs[x];
    	tr[x].siz=tr[l].siz+tr[r].siz+1;
    	tr[x].sum=tr[l].sum+tr[r].sum+tr[x].c.cnt;
    	for(int i=0;i<=1;++i){
    		tr[x].mi[i]=tr[x].mx[i]=tr[x].c.x[i];
    		if(l)tr[x].mi[i]=min(tr[x].mi[i],tr[l].mi[i]),tr[x].mx[i]=max(tr[x].mx[i],tr[l].mx[i]);
    		if(r)tr[x].mi[i]=min(tr[x].mi[i],tr[r].mi[i]),tr[x].mx[i]=max(tr[x].mx[i],tr[r].mx[i]);
    	}
    	//更新子树信息 
    }
    int build(int l,int r,int d){
    	if(l>r)return 0;
    	int x=++tot,mid=l+r>>1;
    	D=d;nth_element(p+l,p+mid,p+r+1);
    	tr[x].c=p[mid];ls[x]=build(l,mid-1,d^1);
    	rs[x]=build(mid+1,r,d^1);pushup(x);return x;
    }
    int A,B,C;
    inline bool check(int x,int y){return A*x+B*y<C;}
    int query(int x){
    	//区间查询 
    	int t=0,res=0;
    	t+=check(tr[x].mi[0],tr[x].mi[1]);
    	t+=check(tr[x].mi[0],tr[x].mx[1]);
    	t+=check(tr[x].mx[0],tr[x].mi[1]);
    	t+=check(tr[x].mx[0],tr[x].mx[1]);
    	if(t==4)return tr[x].sum;//如果这个区间完全在查询范围 
    	else if(t==0)return 0;//完全不在 
    	if(check(tr[x].c.x[0],tr[x].c.x[1]))res+=tr[x].c.cnt;//判断这个点在不在 
    	if(ls[x])res+=query(ls[x]);//分成两边累加答案 
    	if(rs[x])res+=query(rs[x]);
    	return res;
    }
    signed main(){
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=n;++i)
    		scanf("%lld%lld%lld",&p[i].x[0],&p[i].x[1],&p[i].cnt);
    	rt=build(1,n,0);
    	for(int i=1;i<=m;++i){
    		scanf("%lld%lld%lld",&A,&B,&C);
    		printf("%lld
    ",query(rt));
    	}
    	return 0;
    }
    
  • 相关阅读:
    洛谷P1330 封锁阳光大学
    洛谷P1341 无序字母对
    Bzoj1059 [ZJOI2007]矩阵游戏
    POJ2337 Catenyms
    Bzoj2342 [Shoi2011]双倍回文
    Bzoj1009 [HNOI2008]GT考试
    Bzoj3670 [Noi2014]动物园
    POJ2406 Power Strings
    POJ 2752 Seek the Name, Seek the Fame
    POJ3522 Slim Span
  • 原文地址:https://www.cnblogs.com/h-lka/p/12003773.html
Copyright © 2011-2022 走看看