题目地址:https://loj.ac/problem/2555
题目题意我就不讲了..去LOJ上自己看吧233
思路&&分析
首先我们可以知道对于d是有单调性的,对于我们现在已经选定了的一个d,如果这个d是无法满足答案的,那么比它大的值肯定都是不能满足的,如果这个d是可以的,那么比他小的d肯定都是可以的,于是这个d我们可以通过二分答案来解决,对于所有的果汁,我们按d值从大到小排序,然后将p值离散,建立一颗主席树,对于每次二分的mid都用主席树来查询是否可行就行了。(考场上我可能建主席树的时候可能建萎了……于是一直没调出来就放弃了..我好菜啊QAQ)
Code
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
const int maxn=100005;
int n,m,xp[maxn],cnt,rt[maxn],mxd,tot;
struct Tree {
ll suml,sumpl;
int ls,rs;
}tr[maxn<<5];
struct juice {
int d,p,l;
inline void in() {
read(d),read(p),read(l);
}
inline bool operator < (const juice &rhs) const {
return d>rhs.d;
}
}j[maxn];
inline void modify(int &x,int old,int l,int r,int xl,int xpos) {
x=++tot;
tr[x]=tr[old];
tr[x].sumpl+=1ll*xl*xp[xpos];
tr[x].suml+=xl;
if(l==r)
return;
int mid=(l+r)>>1;
if(xpos<=mid)
modify(tr[x].ls,tr[old].ls,l,mid,xl,xpos);
else
modify(tr[x].rs,tr[old].rs,mid+1,r,xl,xpos);
}
inline ll query(int x,int l,int r,ll rl) {
if(tr[x].suml<rl)
return 1e18+1;
if(l==r)
return rl*xp[l];
int mid=(l+r)>>1;
if(tr[tr[x].ls].suml>=rl)
return query(tr[x].ls,l,mid,rl);
else
return tr[tr[x].ls].sumpl+query(tr[x].rs,mid+1,r,rl-tr[tr[x].ls].suml);
}
int main() {
read(n),read(m);
for(int i=1;i<=n;++i)
j[i].in(),xp[++cnt]=j[i].p,mxd=max(mxd,j[i].d);
sort(xp+1,xp+cnt+1);
cnt=unique(xp+1,xp+cnt+1)-xp-1;
sort(j+1,j+n+1);
for(int i=1;i<=n;++i)
modify(rt[i],rt[i-1],1,cnt,j[i].l,lower_bound(xp+1,xp+cnt+1,j[i].p)-xp);
while(m--) {
ll L,P;
read(P),read(L);
int l=1,r=n+1,mid;
while(l<r) {
mid=(l+r)>>1;
if(query(rt[mid],1,cnt,L)>P)
l=mid+1;
else
r=mid;
}
printf("%d\n",l==n+1?-1:j[l].d);
}
}