[CTSC2018]混合果汁
BZOJ
luogu
二分美味度,然后贪心选价格最小的
主席树维护
#define ll long long
#include<bits/stdc++.h>
using namespace std;
const int _=1e5+5;
ll re(){
ll x=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
}
ll g,L;
int n,m,md,mp,tot;
int rt[_],ls[_*20],rs[_*20];
ll s[_*20],sz[_*20],sum[_];
struct node{int p,l;};
vector<node>t[_];
void upd(int&x,int l,int r,int k,int v){
sz[++tot]=sz[x]+v;s[tot]=s[x]+1ll*k*v;
ls[tot]=ls[x];rs[tot]=rs[x];x=tot;
if(l==r)return;int mid=(l+r)>>1;
if(k<=mid)upd(ls[x],l,mid,k,v);
else upd(rs[x],mid+1,r,k,v);
}
ll qsum(int x,int l,int r,ll ne){
if(l==r)return l*ne;
int mid=(l+r)>>1;
if(ne<=sz[ls[x]])return qsum(ls[x],l,mid,ne);
return s[ls[x]]+qsum(rs[x],mid+1,r,ne-sz[ls[x]]);
}
bool check(int mid){
if(sum[mid]<L)return 0;
return qsum(rt[mid],1,mp,L)<=g;
}
int solve(){
int l=0,r=md,ans=-1;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}
return ans;
}
int main(){
n=re(),m=re();
for(int i=1;i<=n;i++){
int d=re(),p=re(),l=re();
t[d].push_back((node){p,l});
md=max(md,d);mp=max(mp,p);
}
for(int i=md;i>=0;i--){
rt[i]=rt[i+1];sum[i]=sum[i+1];
for(int j=0,k=t[i].size();j<k;j++){
upd(rt[i],1,mp,t[i][j].p,t[i][j].l);
sum[i]+=t[i][j].l;
}
}
for(int i=1;i<=m;i++){
g=re(),L=re();
printf("%d
",solve());
}
return 0;
}