再求助线段树 15pts
查看原帖
再求助线段树 15pts
237530
rzh123楼主2023/3/27 18:59

现在改成了:

#include <cstdio>
#include <algorithm>
#include <utility>
#include <numeric>
#define int long long
using namespace std;
constexpr unsigned N=1e5+17;
constexpr long long INF=0x3f3f3f3f3f3f3f3fll;
int n,m,dmx,pmx,pd[N];
struct Seg{
	struct Node{
		int ls,rs;
		long long sl,sp;
	}tr[N*24];
	int nc,rt[N];
	inline int newn(){
		return ++nc;
	}
	inline int clone(int k){
		int u{newn()};
		tr[u]=tr[k];
		return u;
	}
	inline void pup(int k){
		tr[k].sl=tr[tr[k].ls].sl+tr[tr[k].rs].sl,
		tr[k].sp=tr[tr[k].ls].sp+tr[tr[k].rs].sp;
	}
	inline void build(int x){
		rt[x]=newn();
	}
	int modify(int k,int l,int r,int x,long long v){
		if(l>x||r<x) return k;
		k=(k?clone(k):newn());
		if(l==r) return tr[k].sl+=v,tr[k].sp+=1ll*v*x,k;
		int m{(l+r)>>1};
		if(x<=m) tr[k].ls=modify(tr[k].ls,l,m,x,v);
		else tr[k].rs=modify(tr[k].rs,m+1,r,x,v);
		return pup(k),k;
	}
	long long find(int k,int l,int r,long long v){
		//printf("find %lld[%lld,%lld],%lld\n",k,l,r,v);
		if(!k) return INF;
		if(l==r) return l*v;
		int m{(l+r)>>1};
		if(tr[k].ls&&tr[tr[k].ls].sl>=v) return find(tr[k].ls,l,m,v);
		else return tr[tr[k].ls].sp+find(tr[k].rs,m+1,r,v-tr[tr[k].ls].sl);
	}
}tr;
struct Juice{
	int d,p,l;
	inline bool operator<(const Juice &jb)const{
		if(d!=jb.d) return d>jb.d;
		if(p!=jb.p) return p<jb.p;
		return l>jb.l;
		//return d>jb.d;
	}
}a[N];
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i{1};i<=n;++i){
		scanf("%lld%lld%lld",&a[i].d,&a[i].p,&a[i].l);
		pmx=std::max(pmx,a[i].p);
	}sort(a+1,a+n+1); 
	tr.build(0);
	for(int i{1};i<=n;++i){
		if(i==1||a[i].d!=a[i-1].d){
			pd[++dmx]=a[i].d;
			tr.rt[dmx]=tr.rt[dmx-1];
		}
		tr.rt[dmx]=tr.modify(tr.rt[dmx],1,pmx,a[i].p,a[i].l);
	}
	for(int i{1};i<=m;++i){
		long long g,rq;scanf("%lld%lld",&g,&rq);
		int l{1},r{dmx},mid{0},res{0};
		auto check=[&rq,&g](int x)->bool{
			auto t=tr.find(tr.rt[x],1,pmx,rq);
			if(t>=INF) return false;
			if(t>g) return false;
			return true;
		};
		while(l<=r){
			mid=(l+r)>>1;
			if(check(mid)) r=(res=mid)-1;
			else l=mid+1;
		}
		if(!res) puts("-1");
		else printf("%lld\n",pd[res]);
	}
	return 0;
}
/*
 * 

2 1
10 20 5
10 10 5
50 5

 * 
 * */

除了前三个点全 WA

2023/3/27 18:59
加载中...