[2017纪中11-1]背包 二分
2017-11-02 15:13
357 查看
题面
先考虑数据随机。先把物品排好序,每次二分出买的那个价格最大的物品,因为数据随机,买不了多少个就没钱了。
但构造的数据可以卡,于是考虑预处理一个价格前缀和,每次像之前一样二分出能卖的右端点R,然后在二分一个能取走的最长区间[L,R],一次把他们去玩。可以证明这样复杂度是O(nlog^2n)的,因为每次剩下的钱至少变成原来的一半。设钱数为M,[L,R]的价格和于M-C,假设M-C>M/2,那么L-1的价格C’>M-C>M/2,推出C’>C,矛盾。
代码:
先考虑数据随机。先把物品排好序,每次二分出买的那个价格最大的物品,因为数据随机,买不了多少个就没钱了。
但构造的数据可以卡,于是考虑预处理一个价格前缀和,每次像之前一样二分出能卖的右端点R,然后在二分一个能取走的最长区间[L,R],一次把他们去玩。可以证明这样复杂度是O(nlog^2n)的,因为每次剩下的钱至少变成原来的一半。设钱数为M,[L,R]的价格和于M-C,假设M-C>M/2,那么L-1的价格C’>M-C>M/2,推出C’>C,矛盾。
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define ll long long using namespace std; const int maxn=100010; int n,m; ll s[maxn],r[maxn]; struct node { ll v,w; }a[maxn]; bool operator <(const node& p,const node &q) { if(p.v==q.v) return p.w<q.w; return p.v<q.v; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i].v,&a[i].w); sort(a+1,a+n+1); for(int i=1;i<=n;i++) { s[i]=s[i-1]+a[i].v; r[i]=r[i-1]+a[i].w; } while(m--) { int p=n,R=n,q; ll ans=0; node c;c.w=1e13; scanf("%lld",&c.v); while(R>0&&c.v>0) { p=lower_bound(a+1,a+R+1,c)-a-1; q=lower_bound(s,s+R+1,s[p]-c.v)-s; c.v-=s[p]-s[q]; ans+=r[p]-r[q]; R=q; } printf("%lld\n",ans); } return 0; }
相关文章推荐
- [2017纪中11-6]奇怪的队列 树状数组+二分/线段树
- [2017纪中11-9]乘积 数论+分组背包
- [2017纪中11-5]轰炸 强联通分量+DAG最长路
- 2017暑期集训Day 11 背包
- Educational Codeforces Round 11 C. Hard Process(尺取 二分 区间天数最多
- hdu3244Inviting Friends(二分+完全背包)
- [2017纪中11-3][ARC069-F]高考是不可能高考的 2-sat+线段树优化建图
- [2017纪中11-5]好路线 DP
- [2017纪中10-26]摘Galo 树型背包
- [2017纪中10-30]Matrix 二分答案+数论
- [2017纪中11-5]仔细的检查 树hash
- bzoj 4753: [Jsoi2016]最佳团体【01分数规划+二分+树上背包】
- [2017纪中11-1]序列 搜索+IDA*
- [2017纪中11-2]字典序 拓扑排序+优先队列
- [2017纪中11-3]机房比教室好多了 博弈+树型DP
- [2017纪中11-8]购物 贪心+优先队列
- 排序算法-11-二分搜索(Binary Search)
- 一、算法第四版(二分查找、背包、队列、栈)
- [2017纪中11-1]荒诞 欧拉序+状压DP
- [2017纪中11-8]好文章 字符串hash+STL