題意
(遲到的題解吧,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;
}