【题目描述】

蛤布斯有n种商品,第i种物品的价格为ai,价值为bi。有m个人来向蛤布斯购买商品,每个人每种物品只能购买一个。第j个人有cj的钱,他会不停选择一个能买得起的价格最高的商品买走(如果有多个则选择价值最高的)。你需要求出每个人购买的物品的价值和。

【输入数据】

第一行两个正整数n,m。接下来n行每行两个正整数ai,bi。接下来m行每行一个正整数cj。

【输出数据】

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

【样例输入】

5 4

10 5

9 8

7 3

3 4

1 2

20

100

28

18

【样例输出】

15

22

18

10

【数据范围】

对于20%的数据,n,m<=1000。

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

对于100%的数据,n,m<=100000,ai,bi,cj<=10^12。

【题解】

50分解法,将商品以价格为第一关键字、以价值为第二关键字排序,对于每个顾客从大到小枚举,并累计价值和,最后输出。

100分解法,因为商品时有序的,可以想到二分查找,log的复杂度可以明显降低100000的范围带来的影响,但仅仅每次而分出当前可以买到的最大价格的商品是不能得满分的;回归排序操作,可以想到用前缀和来求出一整个可以连续买下的区间的的价格和以及价值和。综上,现二分出起点,再二分出区间并累计,这就是满分算法。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=101111;
typedef long long ll;
int n,m;
bool vis[N];
ll cnt[N];
struct gds{ll w,c;}g[N],ind[N];
bool cmp(gds x,gds y)
{
if(x.w>y.w)return 1;
if(x.w<y.w)return 0;
return x.c>y.c;
}
int b1(ll key)
{
int l=0,r=n-1,mid;
while(l<r){
mid=(l+r)>>1;
if(g[mid].w>key)l=mid+1;
else r=mid-1;
}
while(g[l].w>key)l++;
return l;
}
int b2(int j,ll key)
{
int l=0,r=n-1,mid;
while(l<r){
mid=(l+r)>>1;
if(ind[mid].w-ind[j].w+g[j].w>key)
r=mid-1;
else l=mid+1;
}
while(ind[r].w-ind[j].w+g[j].w>key)r--;
return r;
}
int main()
{
freopen("pack.in","r",stdin);
freopen("pack.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%I64d%I64d",&g[i].w,&g[i].c);
sort(g,g+n,cmp);
ind[0].w=g[0].w;
ind[0].c=g[0].c;
for(int i=1;i<n;i++){
ind[i].w=ind[i-1].w+g[i].w;
ind[i].c=ind[i-1].c+g[i].c;
}
for(int i=0;i<m;i++){
ll c;
int k0=-1,j0=n;
scanf("%I64d",&c);
memset(vis,0,sizeof(vis));
for(int j=b1(c);;j=b1(c)){
if(j0<=j&&j<=k0)break;
if(j>n-1||c-g[j].w<0)break;
int k=b2(j,c);
c-=(ind[k].w-ind[j].w+g[j].w);
cnt[i]+=(ind[k].c-ind[j].c+g[j].c);
j0=j;
k0=k;
}
}
for(int i=0;i<m;i++)
printf("%I64d\n",cnt[i]);
fclose(stdin);
fclose(stdout);
return 0;
}

最新文章

  1. ATM-PROGRAM 关于Proprties的问题
  2. 曲演杂坛--为什么SELECT语句会被其他SELECT阻塞?
  3. TPatch动态补丁系统(iOS)
  4. 【测试】RAC搭建(裸设备)
  5. HttpSolrServer-采用静态工厂方法,创建HttpSolrServer单实例
  6. WinForm中Component Class、User Control及Custom Control的区别和使用-转
  7. linux文件和目录基本操作
  8. SQL中declare申明变量
  9. NodeJS Stream 五:双工流
  10. Vjios P1736 铺地毯【暴力,思维】
  11. jsp的内置对象
  12. BZOJ 5118
  13. POJ 1067 威佐夫博弈
  14. Jenkins的初级应用(2)-Invoke Phing targets
  15. better-scroll项目中遇到的问题
  16. Python - 常用更新命令以及常见库安装
  17. VS 应用模板 所交税和实发工资的运算
  18. Java第06次实验提纲(集合)
  19. 基于SOA的高并发和高可用分布式系统架构和组件详解
  20. [转]oracle制定定时任务(dbms_jobs)

热门文章

  1. [Android]Activity启动过程
  2. iOS开发之多媒体API (转载)
  3. Android 4.4沉浸式状态栏的实现
  4. 传统模式下WebService与WebAPI的相同与不同
  5. 项目管理之道--纪我的新书《PMP项目管理认证学习指南(第4版)》出版并预祝大卖!
  6. SSH新学
  7. InnoDB源码分析--缓冲池(三)
  8. 记一次MongoDB Map&amp;Reduce入门操作
  9. Linux rpm 查询
  10. 错误“Unexpected namespace prefix &quot;xmlns&quot; found for tag LinearLayout”的解决方法(转)