二分$d$, 转为判断判断是否能取到$Lj$升, 再可持久化一下就好了
#include <iostream> #include <algorithm> #include <math.h> #include <cstdio> #include <set> #include <map> #include <string> #include <vector> #include <string.h> #include <queue> #define PER(i,a,n) for(int i=n;i>=a;--i) #define REP(i,a,n) for(int i=a;i<=n;++i) #define mid ((l+r)>>1) #define lc tr[o].l #define rc tr[o].r #define ls lc,l,mid #define rs rc,mid+1,r using namespace std; typedef long long ll; const int N = 1e6+10; int n, m, mx, tot; ll sum[N]; struct {int l,r;ll w,sz;} tr[N<<5]; struct _ {int d,p,l;} a[N]; int T[N]; void update(int &o, int l, int r, int x, int v) { ++tot,tr[tot]=tr[o],tr[o=tot].w+=(ll)x*v,tr[o].sz+=v; if (l==r) return; if (mid>=x) update(ls,x,v); else update(rs,x,v); } ll query(int o, int l, int r, ll x) { if (!o) return 0; if (l==r) return x/l; if (tr[tr[o].l].w>x) return query(ls,x); return query(rs,x-tr[tr[o].l].w)+tr[tr[o].l].sz; } int main() { scanf("%d%d", &n, &m); REP(i,1,n) { scanf("%d%d%d", &a[i].d, &a[i].p, &a[i].l); mx = max(mx, a[i].p); } sort(a+1,a+1+n,[](_ a,_ b){return a.d>b.d;}); REP(i,1,n) { sum[i] = sum[i-1]+a[i].l; T[i]=T[i-1], update(T[i],1,mx,a[i].p,a[i].l); } a[0].d = -1; REP(i,1,m) { ll g, L; scanf("%lld%lld", &g, &L); int l=lower_bound(sum+1,sum+1+n,L)-sum, r=n, ans=0; while (l<=r) { if (query(T[mid],1,mx,g)>=L) ans=mid,r=mid-1; else l=mid+1; } printf("%d\n", a[ans].d); } }