BZOJ 2850: 巧克力王国 KDtree + 估价函数

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个人所能接受的巧克力的美味值之和。

题解: 关键还是在于启发式估价函数.
如果当前点所维护的矩形的极限大的 $ax+by$ 小于等于 $c$ ,说明全部符合要求.
如果极限小值都不符合要求,说明整个矩形都不合法,返回 $0$ 即可.

#include<bits/stdc++.h>
#define maxn 100000 
#define inf 1000000008 
#define mid ((l+r)>>1)
#define ll long long
#define lson (t[x].ch[0]) 
#define rson (t[x].ch[1]) 
using namespace std;
void setIO(string s)
{
    string in=s+".in"; 
    freopen(in.c_str(),"r",stdin); 
}
int n,Q,d; 
ll C, A[4];   
struct Node
{
    int minv[2],maxv[2],p[2],ch[2]; 
    ll sumv,w; 
}t[maxn];  
bool cmp(Node a,Node b)
{
    return a.p[d]==b.p[d]?a.p[d^1]<b.p[d^1]:a.p[d]<b.p[d]; 
}
void pushup(int x,int y)
{
    t[x].minv[0]=min(t[x].minv[0], t[y].minv[0]); 
    t[x].maxv[0]=max(t[x].maxv[0], t[y].maxv[0]); 
    t[x].minv[1]=min(t[x].minv[1], t[y].minv[1]); 
    t[x].maxv[1]=max(t[x].maxv[1], t[y].maxv[1]); 
    t[x].sumv+=t[y].sumv; 
}
int build(int l,int r,int o)
{
    d=o; 
    nth_element(t+l,t+mid,t+1+r,cmp);
    t[mid].minv[0]=t[mid].maxv[0]=t[mid].p[0]; 
    t[mid].minv[1]=t[mid].maxv[1]=t[mid].p[1]; 
    t[mid].ch[0]=t[mid].ch[1]=0; 
    t[mid].sumv=t[mid].w; 
    if(mid>l)
    {
        t[mid].ch[0]=build(l,mid-1,o^1); 
        pushup(mid,t[mid].ch[0]); 
    }
    if(r>mid) 
    {
        t[mid].ch[1]=build(mid+1,r,o^1); 
        pushup(mid,t[mid].ch[1]); 
    }
    return mid; 
} 
ll qmin(int x,ll a,ll b)
{
    ll ans=0; 
    for(int i=0;i<2;++i)
    {
        ans+=min(A[i]*1ll*t[x].minv[i], A[i]*1ll*t[x].maxv[i]); 
    }
    return ans; 
}
ll qmax(int x,ll a,ll b)
{
    ll ans=0; 
    for(int i=0;i<2;++i)
    {
        ans+=max(A[i]*1ll*t[x].minv[i], A[i]*1ll*t[x].maxv[i]); 
    }
    return ans;    
}
ll query(int x,ll a,ll b)
{
    if(qmax(x, a, b) < C) return t[x].sumv; 
    if(qmin(x, a, b) >= C)  return 0; 
    ll ans=0; 
    if(1ll*t[x].p[0]*a+1ll*t[x].p[1]*b < C) ans+=t[x].w; 
    if(lson) ans+=query(lson,a,b); 
    if(rson) ans+=query(rson,a,b); 
    return ans;       
}
int main()
{
   //  setIO("input"); 
    scanf("%d%d",&n,&Q);
    for(int i=1;i<=n;++i)  scanf("%d%d%lld",&t[i].p[0],&t[i].p[1],&t[i].w); 
    int root=build(1,n,0);                 
    while(Q--)
    {
        scanf("%lld%lld%lld",&A[0],&A[1],&C);    
        printf("%lld\n",query(root, A[0], A[1]));    
    }
    return 0; 
}

  

posted @ 2019-06-20 15:29  EM-LGH  阅读(229)  评论(0编辑  收藏  举报