题目描述

蛤布斯有nn种商品,第ii种物品的价格为aiai,价值为bibi。有mm个人来向蛤布斯购买商品,每个人每种物品只能购买一个。第jj个人有cjcj的钱,他会不停选择一个能买得起的价格最高的商品买走(如果有多个则选择价值最高的)。你需要求出每个人购买的物品的价值和。

输入数据

第一行两个正整数nn,mm。接下来nn行每行两个正整数aiai,bibi。接下来mm行每行一个正整数cjcj。

输出数据

mm行,每行一个整数表示答案。

样例输入

5 4
10 5
9 8
7 3
3 4
1 2
20
100
28
18

样例输出

15
22
18
10

数据范围

对于20%的数据,n,m]1000n,m]≤1000。

对于另外30%的数据,ai,bi,cjai,bi,cj在[1,1012][1,1012]中均匀随机。

对于100%的数据,n,m100000ai,bi,cj1012n,m≤100000,ai,bi,cj≤1012。

题目分析


这一题挺有趣的,至少我是这么觉得。我没有想到二分答案的思路,我只想到了排序,然后暴力。接下来我们发现这是构造一个不连续单调的数列,我们可以先处理处前缀和,我想不到这一点。我们两次二分答案,然后得出左右区间即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 100001
#define IL inline
IL char gc(){
    static char buf[1000001],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}IL void write(int x){
    if(x>9)write(x/10);
    putchar(x%10^48);
}template<class T>IL int read(T &x){
    x=0;register char c=gc();
    while(c<47)c=gc();
    while(c>47)x=x*10+(c^48),c=gc();
}struct aa{int a,b;
    friend bool operator<(const aa&x,const aa&y){
        return (x.a^y.a)?x.a<y.a:x.b<y.b;}}a[N];
int sum[N],sum2[N],n,m;
IL int find1(int l,int r,int x){
    int ans=-1,m;
    while (l<=r){
        m=(l+r)>>1;
        a[m].a<=x?ans=m,l=m+1:r=m-1;
    }return ans;
}IL int find2(int l,int r,int x){
    int ans=-1,m;
    while (l<=r){
        m=(l+r)>>1;
        sum[m]>=x?ans=m,r=m-1:l=m+1;
    }return ans;
}IL int check(int R,int res){
    int ans=0,r=find1(1,R,res);
    if (r==-1) return 0;
      int l=find2(0,r-1,sum[r]-res);
    if (l^-1)    ans+=sum2[r]-sum2[l];
    return ans+check(l,res-sum[r]+sum[l]);
}signed main(){
    freopen("pack.in","r",stdin),freopen("pack.out","w",stdout);
    read(n),read(m);
      for (register int i=1;i<=n;i++) read(a[i].a),read(a[i].b);
      sort(a+1,a+n+1);
      for (register int i=1;i<=n;i++)
        sum[i]=sum[i-1]+a[i].a,sum2[i]=sum2[i-1]+a[i].b;
      for (register int sum,i=1;i<=m;i++)
          read(sum),write(check(n,sum)),putchar('\n');
      return 0;
}

代码说明

二分答案可以用upper_bound实现,zzq大佬的代码就是这么实现的。我不给代码,溜了。

尾声:详见下期

posted on 2019-03-18 21:53  aserrrre  阅读(197)  评论(0)    收藏  举报