JZOJ 5440. 【NOIP2017提高A组冲刺11.1】背包
来源:互联网 发布:mac双系统移除win8后 编辑:程序博客网 时间:2024/06/05 05:43
题目大意
有n种商品,第i种物品的价格为ai,价值为bi。有m个人来购买商品,每个人每种物品只能购买一个。第j个人有cj的钱,他会不停选择一个能买得起的价格最高的商品买走(如果有多个则选择价值最高的)。你需要求出每个人购买的物品的价值和。
100%的数据,n,m<=100000,ai,bi,cj<=
题解
有几个性质:
①选择商品的法则唯一:每次选择目前≤cj的ai,如果ai相同就买bi最大的。
有两种解法:
先按照ai从小到大排序,如果ai相等就按照bi从小到大排。那么每次选最右边的合法商品。
第一种,直接二分。这个很方便。因为右节点不断左移,然后暴力二分即可(维护个前缀,因为能卖一整个区间就买一整个区间)。
第二种,线段树(比较麻烦,但是容易想)。直接每次找最右边的区间。
但是,选完最右边一个合法的区间之后,还有剩余的钱买商品怎么办?还要往左找。
所以,这个地方有点难操作。
可以利用全局变量,求出买完右边合法区间之后剩下来的钱(如果要选择右边合法区间的话。具体看代码)。
代码
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define N 100010#define LL long long#define P(a) putchar(a)#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;struct note{ LL sa,sb,mn;};note tr[N*20];struct note1{ LL a,b;};note1 a[N];LL c[N];LL n,m,i,ans,R,x1;LL read(){ LL fh=1,res=0;char ch; while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')fh=-1,ch=getchar(); while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar(); return res*fh;}void write(LL x){ if(x>9)write(x/10); P(x%10+'0');}void writeln(LL x){write(x);P('\n');}void update(LL ps){ tr[ps].sa=tr[ps<<1].sa+tr[(ps<<1)+1].sa; tr[ps].sb=tr[ps<<1].sb+tr[(ps<<1)+1].sb; tr[ps].mn=tr[ps<<1].mn<tr[(ps<<1)+1].mn?tr[ps<<1].mn:tr[(ps<<1)+1].mn;}void build(LL ps,LL l,LL r){ if(l==r){ tr[ps].sa=a[l].a; tr[ps].sb=a[l].b; tr[ps].mn=a[l].a; return; } LL wz=(l+r)>>1; build(ps<<1,l,wz); build((ps<<1)+1,wz+1,r); update(ps);}void find(LL ps,LL l,LL r,LL x,LL bl){ if(bl)x1=x; if(!x)return; if(l==r){ if(x>=tr[ps].sa){ ans+=tr[ps].sb; if(bl)x1=x-tr[ps].sa; } return; } LL wz=(l+r)>>1; if(x>=tr[(ps<<1)+1].sa){ ans+=tr[(ps<<1)+1].sb; find(ps<<1,l,wz,x-tr[(ps<<1)+1].sa,bl); } else{ if(x>=tr[(ps<<1)+1].mn){ find((ps<<1)+1,wz+1,r,x,1); find(ps<<1,l,wz,x1,bl); } else if(x>=tr[ps<<1].mn){ find(ps<<1,l,wz,x,bl); } }}bool cmp(note1 x,note1 y){return x.a<y.a || (x.a==y.a && x.b<y.b);}int main(){ n=read(),m=read(); fo(i,1,n)a[i].a=read(),a[i].b=read(); sort(a+1,a+n+1,cmp); build(1,1,n); fo(i,1,m){ c[i]=read();ans=0;R=c[i]; find(1,1,n,R,0); writeln(ans); } return 0;}
阅读全文
1 0
- JZOJ 5440. 【NOIP2017提高A组冲刺11.1】背包
- JZOJ 5440. 【NOIP2017提高A组冲刺11.1】背包
- JZOJ 5441. 【NOIP2017提高A组冲刺11.1】序列
- 【JZOJ 5442】【NOIP2017提高A组冲刺11.1】荒诞
- 【JZOJ 5441】【NOIP2017提高A组冲刺11.1】序列
- JZOJ 5442. 【NOIP2017提高A组冲刺11.1】荒诞
- JZOJ 5441. 【NOIP2017提高A组冲刺11.1】序列
- Jzoj5440 【NOIP2017提高A组冲刺11.1】背包
- JZOJ5440. 【NOIP2017提高A组冲刺11.1】背包
- 【JZOJ 5445】【NOIP2017提高A组冲刺11.2】失格
- JZOJ 5443. 【NOIP2017提高A组冲刺11.2】字典序
- jzoj【NOIP2017提高A组冲刺11.2】失格
- JZOJ 5444. 【NOIP2017提高A组冲刺11.2】救赎
- JZOJ 5445. 【NOIP2017提高A组冲刺11.2】失格
- JZOJ 5445. 【NOIP2017提高A组冲刺11.2】失格
- 【JZOJ 5451】【NOIP2017提高A组冲刺11.4】Genocide
- 【JZOJ 5449】【NOIP2017提高A组冲刺11.4】Pacifist
- 【JZOJ 5452】【NOIP2017提高A组冲刺11.5】轰炸
- 玩转SpringBoot
- 剑指offer------回溯法
- 11月的雨
- 1025. 反转链表 (25)
- 1用switch语句从控制台输入100以内的分数判断优秀,良好,及格不及格属于哪一个区间
- JZOJ 5440. 【NOIP2017提高A组冲刺11.1】背包
- [笔记]eclipse保存包含有中文字符的源代码文件出错[了解字符集]
- bzoj3192 [JLOI2013]删除物品 树状数组
- 单点登录原理与简单实现
- JavaScript--《剑指offer》-题二十七
- Unity3d入门基础之UGUI-基本控件的学习-搭建界面的常规步骤
- 689. Maximum Sum of 3 Non-Overlapping Subarrays 【Hard】 动态规划
- JavaWeb之文件上传、下载
- 习题6.4作业提交