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);
    }
}

posted @ 2019-09-28 13:45  蒟蒻--lichenxi  阅读(168)  评论(0编辑  收藏  举报