洛谷 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\)个人所能接受的巧克力的美味值之和。
说明
对于\(100\%\)的数据,\(1\le n,m\le 50000,-10^9\le a_i,b_i,x_i,y_i\le 10^9\)。
kdtree 搞一下就行了,没有插入就不需要重构
然后复杂度是为什么呢(
Code:
#include <cstdio>
#include <algorithm>
#include <cctype>
#define ll long long
const int N=5e4+10;
const int K=2;
const ll inf=1ll<<45;
int read()
{
int x=0,f=1;char c=getchar();
while(!isdigit(c)) f=c=='-'?0:1,c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return f?x:-x;
}
#define ls ch[now][0]
#define rs ch[now][1]
int ch[N][2],L[N][2],R[N][2],p[N][2],val[N],s[N];
ll sum[N],a,b,c;
int n,m,nk,root;
void ckmin(ll &mi,ll yuy){mi=mi<yuy?mi:yuy;}
void ckmax(ll &mx,ll yuy){mx=mx>yuy?mx:yuy;}
using std::min;
using std::max;
void updata(int now)
{
sum[now]=sum[ls]+sum[rs]+val[now];
for(int i=0;i<K;i++)
{
L[now][i]=R[now][i]=p[now][i];
if(ls) L[now][i]=min(L[now][i],L[ls][i]),R[now][i]=max(R[now][i],R[ls][i]);
if(rs) L[now][i]=min(L[now][i],L[rs][i]),R[now][i]=max(R[now][i],R[rs][i]);
}
}
bool cmp(int a,int b){return p[a][nk]<p[b][nk];}
void build(int &now,int l,int r,int k)
{
if(l>r) return;
int mid=l+r>>1;nk=k;
std::nth_element(s+l,s+mid,s+r+1,cmp);
now=s[mid];
build(ls,l,mid-1,k^1),build(rs,mid+1,r,k^1);
updata(now);
}
void get(int now,ll &mi,ll &mx)
{
ll bee=a*L[now][0]+b*L[now][1];
ckmin(mi,bee),ckmax(mx,bee);
bee=a*L[now][0]+b*R[now][1];
ckmin(mi,bee),ckmax(mx,bee);
bee=a*R[now][0]+b*L[now][1];
ckmin(mi,bee),ckmax(mx,bee);
bee=a*R[now][0]+b*R[now][1];
ckmin(mi,bee),ckmax(mx,bee);
}
ll query(int now)
{
if(!now) return 0;
ll mi=inf,mx=-inf;
get(now,mi,mx);
if(mx<c) return sum[now];
if(mi>=c) return 0;
return (a*p[now][0]+b*p[now][1]<c?val[now]:0)+query(ls)+query(rs);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
{
p[i][0]=read(),p[i][1]=read(),sum[i]=val[i]=read();
s[i]=i;
}
build(root,1,n,0);
for(int i=1;i<=m;i++)
{
a=read(),b=read(),c=read();
printf("%lld\n",query(root));
}
return 0;
}
2019.2.5