cstc2018 混合果汁
LOJ
好简单的题。
对美味度排序,然后价格为下标建立主席树,查询时二分就行了
代码:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
#define rg register
void read(int &x){
char ch;bool ok;
for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
}
void read1(long long &x){
char ch;bool ok;
for(ok=0,ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')ok=1;
for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());if(ok)x=-x;
}
const int maxn=1e5+10,inf=1e5;
int n,m,id,rt[maxn*4],ls[maxn*50],rs[maxn*50];
long long s[maxn*50],ss[maxn*50];
struct oo{int d,p,l;}a[maxn];
bool cmp(oo a,oo b){return a.d>b.d;}
void update(int x){
s[x]=s[ls[x]]+s[rs[x]];
ss[x]=ss[ls[x]]+ss[rs[x]];
}
void change(int &k,int x,int l,int r,int a,int b){
k=++id,ls[k]=ls[x],rs[k]=rs[x],s[k]=s[x],ss[k]=ss[x];
if(l==r)return s[k]+=b,ss[k]+=1ll*b*l,void();int mid=(l+r)>>1;
if(a<=mid)change(ls[k],ls[x],l,mid,a,b);
else change(rs[k],rs[x],mid+1,r,a,b);
update(k);
}
long long get(int k,int l,int r,long long a){
if(l==r)return a*l;long long ll=s[ls[k]];int mid=(l+r)>>1;
if(a<=ll)return get(ls[k],l,mid,a);
else return ss[ls[k]]+get(rs[k],mid+1,r,a-ll);
}
bool check(int now,long long x,long long y){return s[rt[now]]>=y?(get(rt[now],1,inf,y)>x):1;}
int main(){
read(n),read(m);
for(rg int i=1;i<=n;i++)read(a[i].d),read(a[i].p),read(a[i].l);
sort(a+1,a+n+1,cmp);
for(rg int i=1;i<=n;i++)change(rt[i],rt[i-1],1,inf,a[i].p,a[i].l);
for(rg int i=1;i<=m;i++){
long long x,y;
read1(x),read1(y);
int l=1,r=n;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid,x,y))l=mid+1;
else r=mid-1;
}
printf("%d\n",!a[l].d?-1:a[l].d);
}
}