BZOJ.4946.[NOI2017]蔬菜(贪心 离线)
因为有删除,考虑倒序处理某个p的询问。
那么每天删除xi的蔬菜就变成了每天运来xi的蔬菜。那么我们取当前最优的即可,早取晚取都一样,不需要留给后面取,还能给后面更优的留出空间。
这样就只需考虑现在了。于是我们能得到p为某个值的答案。多次询问显然需要递推。
而p-1与p相比只是少卖了m的蔬菜。把收益最小的m个删掉即可。
注意堆的插入删除顺序。
复杂度\(O(mqlogn)\)。
还有一种求询问p的方法,是直接按蔬菜价值排序,然后每次找到其出现位置往前覆盖。如果某天已卖m则用并查集合并掉。
递推的时候sort一遍挨着删就可以。
感觉离散化后线段树可做,第一次购买收益单独算一个,每个节点维护区间当前蔬菜种数、蔬菜总量、每天减少量。
正序做,每一天就选m个最大的,然后减掉这m个。
在某种蔬菜消失的那天直接Delete掉这种蔬菜(如果剩下1个下一天则Delete掉拆开的第一次购买收益)。
这样复杂度还与m无关。
不过...算了我就想想...写了写就弃了。
//9424kb 1132ms
#include <queue>
#include <cstdio>
#include <cctype>
#include <vector>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 400000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define mp std::make_pair
#define pr std::pair<LL,int>
#define MAX 100000
typedef long long LL;
const int N=1e5+3;
int A[N],S[N],tot[N],dec[N],use[N];
LL Ans[N];
std::vector<int> v[N];
std::queue<int> tmp;
std::priority_queue<pr> q1;
std::priority_queue<pr,std::vector<pr>,std::greater<pr> > q2;
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
int main()
{
int n=read(),m=read(),Q=read();
for(int i=1; i<=n; ++i)
{
A[i]=read(),S[i]=read(),tot[i]=read(),dec[i]=read();
if(!dec[i]) v[MAX].push_back(i);//上界!
else v[std::min(MAX,(tot[i]+dec[i]-1)/dec[i])].push_back(i);
}
LL ans=0;
for(int i=MAX; i; --i)
{
for(int j=0,k,l=v[i].size(); j<l; ++j)//处理第一次购买
k=v[i][j], q1.push(mp(A[k]+S[k],k));
for(int l=m; l&&!q1.empty(); q1.pop())
{
int x=q1.top().second;
if(!use[x])
use[x]=1, ans+=q1.top().first, q1.push(mp(A[x],x)), --l;
else
{
int cnt=std::min(l,tot[x]-use[x]-(i-1)*dec[x]);
ans+=1ll*q1.top().first*cnt, l-=cnt;
if((use[x]+=cnt)!=tot[x]/*x=0可能会用完!*/) tmp.push(x);//delete
}
}
while(!tmp.empty()) q1.push(mp(A[tmp.front()],tmp.front())), tmp.pop();
}
Ans[MAX]=ans; int sum=0;
for(int i=1; i<=n; sum+=use[i++])
if(use[i]==1) q2.push(mp(A[i]+S[i],i));
else if(use[i]) q2.push(mp(A[i],i));
for(int i=MAX-1; i; --i)
{
Ans[i]=ans=Ans[i+1];
if(sum<=m*i) continue;//总数不够!
for(int l=sum-i*m/*同上!*/; l&&!q2.empty(); )
{
int x=q2.top().second;
if(use[x]==1) ans-=q2.top().first, --l, q2.pop();
else
{
int cnt=std::min(l,use[x]-1);
ans-=1ll*q2.top().first*cnt, l-=cnt;
if((use[x]-=cnt)==1) q2.pop(), q2.push(mp(A[x]+S[x],x));
}
}
sum=i*m, Ans[i]=ans;
}
while(Q--) printf("%lld\n",Ans[read()]);
return 0;
}
BZOJ.4946.[NOI2017]蔬菜(贪心 离线)的更多相关文章
- 【刷题】BZOJ 4946 [Noi2017]蔬菜
Description http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf Solution 网上大部分都是并查集写法,但是有大神写了非并查集写 ...
- 4946: [Noi2017]蔬菜
4946: [Noi2017]蔬菜 http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf 分析: 贪心. 首先可以将一个蔬菜拆成两个,一个是有加成 ...
- [NOI2017]蔬菜 贪心
题面: [NOI2017]蔬菜 题解: 首先每天蔬菜会变质这点并不好处理,我们考虑让时间倒流,从后向前处理,这样的话就相当于每天都会得到一定量的蔬菜. 这样做有什么好处呢? 我们可以发现一个性质:如果 ...
- NOI2017蔬菜(贪心)
小 N 是蔬菜仓库的管理员,负责设计蔬菜的销售方案. 在蔬菜仓库中,共存放有 n 种蔬菜,小 N 需要根据不同蔬菜的特性,综合考虑各 方面因素,设计合理的销售方案,以获得最多的收益. 在计算销售蔬菜的 ...
- 【BZOJ4946】[NOI2017]蔬菜(贪心)
[BZOJ4946][NOI2017]蔬菜(贪心) 题面 BZOJ 洛谷 UOJ 题解 忽然发现今年\(NOI\)之前的时候切往年\(NOI\)的题目,就\(2017\)年的根本不知道怎么下手(一定是 ...
- bzoj4946: [Noi2017]蔬菜 神烦贪心
题目链接 bzoj4946: [Noi2017]蔬菜 题解 挺神的贪心 把第次买的蔬菜拆出来,记下每种蔬菜到期的日期,填第一单位蔬菜比其他的要晚 按价格排序后,贪心的往前面可以填的位置填就可以了.找可 ...
- [NOI2017]蔬菜
[NOI2017]蔬菜 题目描述 大意就是有\(n\)种物品,第\(i\)个物品有\(c_i\)个,单价是\(a_i\).然后每天你可以卖出最多\(m\)个物品.每天结束后第\(i\)种物品会减少\( ...
- BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流
题目链接: [Noi2017]蔬菜 题目大意:有$n$种蔬菜,每种蔬菜有$c_{i}$个,每种蔬菜每天有$x_{i}$个单位会坏掉(准确来说每天每种蔬菜坏掉的量是$x_{i}-$当天这种蔬菜卖出量), ...
- [NOI2017]蔬菜——时光倒流+贪心
题目链接 题解: 貌似一眼看过去是一个贪心. 其他的算法要记录的东西就太多了. 部分分其实很高.但是没有什么提示. 想一些套路:二分?不行还要贪心判断. 分治?前后取法是有影响的. 时光倒流? 也许可 ...
随机推荐
- ftp服务部署
注:Centos7环境,添加用户指定目录后默认其为此用户的共享目录. chroot_local_user=YES chroot_list_enable=YES # (default follows) ...
- 思考的乐趣----matrix67数学笔记:最精妙的无字证明
从<思考的乐趣----matrix67数学笔记>一书中看到这个证明,据说在mathoverflow网站上这个无字证明获得了最多的投票! http://mathoverflow.net/qu ...
- 360 / 小米 / 百度 随身wifi Ubuntu 下作为无线网卡使用
这篇文章说得其实很好了,http://www.freemindworld.com/blog/2013/131010_360_wifi_in_linux.shtml 不过因为专利问题,官网貌似不直接提供 ...
- df -h执行卡住不动问题解决【转】
昨天生产环境报日志写不进去了,因此 登陆线上环境后,习惯用df -h命令查看空间使用情况,结果发现该命令执行半天也没有返回. 因此使用mount命令查看该机器上的目录: [conversant@swi ...
- SharePoint 2013 另一个程序正在使用此文件,进程无法访问。 (异常来自 HRESULT:0x80070020)
环境:SharePoint 2013 + Windows Server 2012 R2 在管理中心新建一个Web Application,端口为:88.顺利创建网站集后,打开访问却提示:无法显示此页 ...
- 【转】Java JUnit 单元测试小结
原文链接:https://segmentfault.com/a/1190000006731125 测试类型 单元测试(Unit test) 单元测试关注单一的类. 它们存在的目的是检查这个类中的代码是 ...
- Demo004 迷宫的生成与遍历的代码审查
1.传送门 合作伙伴: 嚯唶 CnBlogs: 嚯唶 Coding:Rst321 代码: 迷宫的遍历与生成 2. 作业要求 (1). 首先在同学中找一个同伴,范围不限,可以在1~5班中随意组合,建议尽 ...
- opencv的级联分类器(mac)
级联分类器的介绍:级联分类器训练 因为要训练负样本,windows电脑有些问题,所以就只能有mac进行训练. 在windows中训练,准备了负样本之后,进行三步. 1.opencv_createsam ...
- c语言字符串函数大全(转)
函数名: stpcpy 功 能: 拷贝一个字符串到另一个 用 法: char *stpcpy(char *destin, char *source); 程序例: #include <stdio. ...
- Android 隐藏、显示软键盘方法
隐藏软键盘的终极方法: public class SoftKeyboardUtil { /** * 隐藏软键盘(只适用于Activity,不适用于Fragment) */ public static ...