下周就省选了,好虚啊
解析:
首先第一眼看到这道题就有个nm再带log的做法,就是直接二分就行了
然后我们发现这样的话没有把他给你的果汁的信息利用起来,所以我们直接对果汁按美味度排个序,套个主席树,再二分就做完了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll inf=2e18;
const int N=1e5+10;
struct node{
ll sl,g;
int l,r;
};
node tree[N<<7];
struct v_d{
ll d,p,l;
};
v_d v[N];
int root[N];
int n,m,d_max,cnt;
ll g,l;
bool cmp(v_d x,v_d y){
return x.d>y.d;
}
ll pan(ll x,ll y)
{
if (x==inf||y==inf) return inf;
if (x+y>1e18) return inf;
else return x+y;
}
void build(int l,int r,int k)
{
cnt=max(cnt,k);
if (l==r) return;
else {
int mid=(l+r)/2;
tree[k].l=(k<<1); tree[k].r=(k<<1|1);
build(l,mid,k<<1);
build(mid+1,r,k<<1|1);
}
}
void update(int x)
{
tree[x].sl=tree[tree[x].l].sl+tree[tree[x].r].sl;
tree[x].g=pan(tree[tree[x].l].g,tree[tree[x].r].g);
}
void lalala(int nowr,int now,int l,int r,v_d x)
{
if (l==r) {
tree[now].sl=tree[nowr].sl+x.l;
tree[now].g=pan(tree[nowr].g,x.l*x.p);
}
else {
int mid=(l+r)/2;
if (x.p<=mid) {
tree[now].r=tree[nowr].r; tree[now].l=++cnt; lalala(tree[nowr].l,tree[now].l,l,mid,x);
}
else {
tree[now].l=tree[nowr].l; tree[now].r=++cnt; lalala(tree[nowr].r,tree[now].r,mid+1,r,x);
}
update(now);
}
}
bool pan1(int x,int l,int r,ll g,ll lim)
{
if (lim>tree[x].sl) return 0;
if (lim==tree[x].sl) return (g>=tree[x].g);
if (l==r) return (g>=(ll)l*lim);
int mid=(l+r)/2;
if (tree[tree[x].l].sl<lim) {
g-=tree[tree[x].l].g;
if (g<=0) return 0;
return pan1(tree[x].r,mid+1,r,g,lim-tree[tree[x].l].sl);
}
else return pan1(tree[x].l,l,mid,g,lim);
}
ll findans(int l,int r,ll g,ll lim)
{
if (l>r) return inf;
int mid=(l+r)/2;
if (pan1(root[mid],1,d_max,g,lim)) return min((ll)mid,findans(l,mid-1,g,lim));
else return findans(mid+1,r,g,lim);
}
int main()
{
scanf("%d%d",&n,&m);
d_max=0;
for (int i=1;i<=n;i++) {
scanf("%lld%lld%lld",&v[i].d,&v[i].p,&v[i].l);
d_max=max(d_max,(int)v[i].p);
}
sort(v+1,v+n+1,cmp);
root[0]=1;
build(1,d_max,1);
for (int i=1;i<=n;i++) {
root[i]=++cnt;
lalala(root[i-1],root[i],1,d_max,v[i]);
}
for (int i=1;i<=m;i++){
scanf("%lld%lld",&g,&l);
ll s=findans(1,n,g,l);
if (s==inf) printf("%d\n",-1);
else
printf("%lld\n",v[s].d);
}
}