1. 程式人生 > >[CTSC2018]混合果汁

[CTSC2018]混合果汁

pri || efi code i++ define () using ble

[CTSC2018]混合果汁

BZOJ
luogu
二分美味度,然後貪心選價格最小的
主席樹維護

#define ll long long
#include<bits/stdc++.h>
using namespace std;
const int _=1e5+5;
ll re(){
    ll x=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*w;
}
ll g,L;
int n,m,md,mp,tot;
int rt[_],ls[_*20],rs[_*20];
ll s[_*20],sz[_*20],sum[_];
struct node{int p,l;};
vector<node>t[_];
void upd(int&x,int l,int r,int k,int v){
    sz[++tot]=sz[x]+v;s[tot]=s[x]+1ll*k*v;
    ls[tot]=ls[x];rs[tot]=rs[x];x=tot;
    if(l==r)return;int mid=(l+r)>>1;
    if(k<=mid)upd(ls[x],l,mid,k,v);
    else upd(rs[x],mid+1,r,k,v);
}
ll qsum(int x,int l,int r,ll ne){
    if(l==r)return l*ne;
    int mid=(l+r)>>1;
    if(ne<=sz[ls[x]])return qsum(ls[x],l,mid,ne);
    return s[ls[x]]+qsum(rs[x],mid+1,r,ne-sz[ls[x]]);
}
bool check(int mid){
    if(sum[mid]<L)return 0;
    return qsum(rt[mid],1,mp,L)<=g;
}
int solve(){
    int l=0,r=md,ans=-1;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid))ans=mid,l=mid+1;
        else r=mid-1;
    }
    return ans;
}
int main(){
    n=re(),m=re();
    for(int i=1;i<=n;i++){
        int d=re(),p=re(),l=re();
        t[d].push_back((node){p,l});
        md=max(md,d);mp=max(mp,p);
    }
    for(int i=md;i>=0;i--){
        rt[i]=rt[i+1];sum[i]=sum[i+1];
        for(int j=0,k=t[i].size();j<k;j++){
            upd(rt[i],1,mp,t[i][j].p,t[i][j].l);
            sum[i]+=t[i][j].l;
        }
    }
    for(int i=1;i<=m;i++){
        g=re(),L=re();
        printf("%d\n",solve());
    }
    return 0;
}

[CTSC2018]混合果汁