Luogu P4062 [CTSC2018]混合果汁

二分$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);
	}
}

猜你喜欢

转载自www.cnblogs.com/uid001/p/10462779.html