题意
(迟到的题解吧,CTSC略略略,但这道题确实挺基础的qwq)
有n种果汁,m个小朋友,第i种果汁有个美味度di,每升的价格pi,和最多有li升。第i个小朋友付的价格不超过gi,但要获得至少Li升的果汁,问美味度最小值的最大值是多少?
题解
一眼可以看出是二分答案的吧,然后考虑贪心,暴力的话是把美味度>=d[i]的p数组排序,然后从小的开始取,这样子是正确的,但太慢了,所以考虑用数据结构维护,类似于区间第k大的思路,我们以p为线段树下标,点上存价格在[l,r]之间的果汁有多少。用可持久化线段树第i棵树就表示1~i的果汁所对应的线段树。然后…好像就解决的吧?感觉别的没什么好说的了(要不前缀和了解一下?emm这题确实挺简单的ww
//Suplex
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 200200
using namespace std;
int n,m,maxp,s,cnt,tot,q[N],opp[N],root[N];
long long G,LL,sum[N];
struct leo{
int d,p,l;
}a[N];
struct Segment_tree{
int l,r;
long long val,LL;
}t[2000000];
bool cmp(leo a,leo b)
{
return a.d<b.d;
}
inline void modify(int &rt,int p,int l,int r,int x,long long delta)
{
rt=++cnt;
t[rt].l=t[p].l;t[rt].r=t[p].r;
t[rt].LL=t[p].LL;t[rt].val=t[p].val;
t[rt].val+=1ll*x*delta;t[rt].LL+=delta;
if(l==r) return;
int mid=(l+r)>>1;
if(x<=mid) modify(t[rt].l,t[p].l,l,mid,x,delta);
else modify(t[rt].r,t[p].r,mid+1,r,x,delta);
}
long long query(int rt,int p,int l,int r,long long rest)
{
if(!rt) return 0;
if(l==r) return rest*(long long)r;
int mid=(l+r)>>1;
long long lsum=t[t[rt].l].LL-t[t[p].l].LL;
if(rest<=lsum) return query(t[rt].l,t[p].l,l,mid,rest);
else return t[t[rt].l].val-t[t[p].l].val+query(t[rt].r,t[p].r,mid+1,r,rest-lsum);
}
bool check(int d,long long G,long long LL)
{
int fr=opp[d];
//printf("%d %lld\n",d,query(root[n],root[fr-1],1,maxp,LL));
if(sum[n]-sum[fr-1]<LL) return false;
if(query(root[n],root[fr-1],1,maxp,LL)<=G) return true;
return false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i].d,&a[i].p,&a[i].l);
maxp=max(maxp,a[i].p);
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i].l;
for(int i=1;i<=n;i++) modify(root[i],root[i-1],1,maxp,a[i].p,a[i].l);
for(int i=n;i;i--) opp[a[i].d]=i;
for(int i=1;i<=n;i++) if(a[i].d != a[i-1].d) q[++tot]=a[i].d;
while(m--){
scanf("%lld%lld",&G,&LL);
int L=1,R=tot;
while(L<R){
int mid=(L+R+1)>>1;
if(check(q[mid],G,LL)) L=mid;
else R=mid-1;
}
if(check(q[R],G,LL)) printf("%d\n",q[R]);else puts("-1");
}
return 0;
}