[CTSC2018]混合果汁juice(二分+主席树)

题目地址: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);
    }
}

猜你喜欢

转载自blog.csdn.net/effervescence/article/details/80371869