神仙题啊!

早上开了两个多小时,终于肝出来了,真香

我们考虑从第 \(10^5\) 天开始递推,先生成 \(p=10^5\) 的解,然后逐步推出 \(p-1,...,2,1\) 的解。

那怎么推出 \(p=10^5\) 的解呢?

现在将题目转化成不停进货然后取 \(m\) 个最大的问题,然后删除最大并 \(push\) 进去。这我们可以想到大根堆。

但是由于政策 增加题目难度,有一个 \(s\)。我们需要先将 \((a_i+s_i,i)\) \(push\) 进去,然后用掉了以后将 \((a_i,i)\) \(push\) 进去。

因为在第 \(i\) 天买了一种蔬菜,当天就无需再用,我们考虑用一个栈存储一下当天用了不是 \(a+s\) 的蔬菜,

然后 \(p=10^5\) 的解生成完了以后,现在就是生成其他解了。

我们每次将最小的 \(sum-i*m\) 个取出然后删除。此时我们也要特判政策。

答案要开 \(long\ long\),时间复杂度 \(O(pm\log n)\)

\(Code\ Below:\)

#include <bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define mp make_pair
#define F first
#define S second
using namespace std;
const int maxn=100000+10;
const int lim=100000;
int n,m,k,a[maxn],s[maxn],c[maxn],x[maxn],used[maxn],sum,top;
vector<int> v[maxn];ll ans[maxn];pii sta[maxn];
priority_queue<pii> pq; inline int read(){
register int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return (f==1)?x:-x;
} int main()
{
n=read(),m=read(),k=read();
for(int i=1;i<=n;i++){
a[i]=read(),s[i]=read(),c[i]=read(),x[i]=read();
if(x[i]==0) v[lim].push_back(i);
else v[(c[i]+x[i]-1)/x[i]].push_back(i);
}
pii u;int rest;
for(int i=lim;i>=1;i--){
for(int j=0;j<v[i].size();j++) pq.push(mp(a[v[i][j]]+s[v[i][j]],v[i][j]));
for(int j=m;j>=1&&!pq.empty();){
u=pq.top(),pq.pop();
if(!used[u.S]){
used[u.S]++;ans[lim]+=u.F;j--;
if(used[u.S]!=c[u.S]) pq.push(mp(a[u.S],u.S));
}
else {
rest=min(j,c[u.S]-used[u.S]-(i-1)*x[u.S]);
ans[lim]+=(ll)rest*a[u.S];used[u.S]+=rest;j-=rest;
if(used[u.S]!=c[u.S]) sta[++top]=mp(a[u.S],u.S);
}
}
while(top) pq.push(sta[top--]);
}
while(!pq.empty()) pq.pop();
for(int i=1;i<=n;i++) sum+=used[i];
for(int i=1;i<=n;i++){
if(used[i]==1) pq.push(mp(-a[i]-s[i],i));
else if(used[i]) pq.push(mp(-a[i],i));
}
for(int i=lim-1;i>=1;i--){
ans[i]=ans[i+1];
while(sum>i*m&&!pq.empty()){
u=pq.top(),pq.pop();u.F=-u.F;
if(used[u.S]==1) ans[i]-=u.F,sum--,used[u.S]=0;
else {
rest=min(sum-i*m,used[u.S]-1);
sum-=rest;used[u.S]-=rest;ans[i]-=(ll)rest*a[u.S];
if(used[u.S]==1) pq.push(mp(-a[u.S]-s[u.S],u.S));
else pq.push(mp(-a[u.S],u.S));
}
}
}
while(k--) printf("%lld\n",ans[read()]);
return 0;
}

[NOI2017]蔬菜(贪心)的更多相关文章

  1. [NOI2017]蔬菜 贪心

    题面: [NOI2017]蔬菜 题解: 首先每天蔬菜会变质这点并不好处理,我们考虑让时间倒流,从后向前处理,这样的话就相当于每天都会得到一定量的蔬菜. 这样做有什么好处呢? 我们可以发现一个性质:如果 ...

  2. NOI2017蔬菜(贪心)

    小 N 是蔬菜仓库的管理员,负责设计蔬菜的销售方案. 在蔬菜仓库中,共存放有 n 种蔬菜,小 N 需要根据不同蔬菜的特性,综合考虑各 方面因素,设计合理的销售方案,以获得最多的收益. 在计算销售蔬菜的 ...

  3. BZOJ.4946.[NOI2017]蔬菜(贪心 离线)

    题目链接 因为有删除,考虑倒序处理某个p的询问. 那么每天删除xi的蔬菜就变成了每天运来xi的蔬菜.那么我们取当前最优的即可,早取晚取都一样,不需要留给后面取,还能给后面更优的留出空间. 这样就只需考 ...

  4. 【BZOJ4946】[NOI2017]蔬菜(贪心)

    [BZOJ4946][NOI2017]蔬菜(贪心) 题面 BZOJ 洛谷 UOJ 题解 忽然发现今年\(NOI\)之前的时候切往年\(NOI\)的题目,就\(2017\)年的根本不知道怎么下手(一定是 ...

  5. bzoj4946: [Noi2017]蔬菜 神烦贪心

    题目链接 bzoj4946: [Noi2017]蔬菜 题解 挺神的贪心 把第次买的蔬菜拆出来,记下每种蔬菜到期的日期,填第一单位蔬菜比其他的要晚 按价格排序后,贪心的往前面可以填的位置填就可以了.找可 ...

  6. [NOI2017]蔬菜

    [NOI2017]蔬菜 题目描述 大意就是有\(n\)种物品,第\(i\)个物品有\(c_i\)个,单价是\(a_i\).然后每天你可以卖出最多\(m\)个物品.每天结束后第\(i\)种物品会减少\( ...

  7. BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流

    题目链接: [Noi2017]蔬菜 题目大意:有$n$种蔬菜,每种蔬菜有$c_{i}$个,每种蔬菜每天有$x_{i}$个单位会坏掉(准确来说每天每种蔬菜坏掉的量是$x_{i}-$当天这种蔬菜卖出量), ...

  8. 4946: [Noi2017]蔬菜

    4946: [Noi2017]蔬菜 http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf 分析: 贪心. 首先可以将一个蔬菜拆成两个,一个是有加成 ...

  9. BZOJ4946 NOI2017蔬菜(贪心+堆)

    容易想到一个费用流做法:将每种蔬菜拆成p种,对应p个过期时间,每一种向可以卖的时间连边,第一次卖的奖励算在最晚过期的一种里.对于天数动态加点.不过这样边数太多了,因为第i天能卖的第i-1天一定能卖,可 ...

  10. uoj318 [NOI2017]蔬菜 【贪心 + 堆 + 并查集】

    题目链接 uoj 题解 以前看别人博客,在考场上用费用流做,一直以为这题是毒瘤网络流题 没想到竟然是贪心模拟题... 如果只有一个蔬菜呢?这就是一个经典的普及难度的贪心,正着推面临优先选择的困难,而逆 ...

随机推荐

  1. SQL Server 2008中的MERGE(不仅仅是合并)

    SQL Server 2008中的MERGE语句能做很多事情,它的功能是根据源表对目标表执行插入.更新或删除操作.最典型的应用就是进行两个表的同步. 下面通过一个简单示例来演示MERGE语句的使用方法 ...

  2. 海港(NOIP2016)

    题目链接:海港 这一题怎么样呢?还好吧,也不是太难,没有用到什么特殊的算法,但写法还是很值得学习的.下面讲一下思路: 我们维护三个队列(这里我们采用自己手写的队列,因为这比STL的要快,不过这一题,S ...

  3. python中将两个数组压缩成一个数组

    我们有时候会遇到一个问题将两个数组一一对应的压缩起来: 两个都是字符串: 列表解析[''.join(i) for i in zip(list_1, list_2)] map(lambda x,y:x+ ...

  4. ubuntu禁用n卡驱动(进系统卡死)

    显卡驱动 该发行版依旧内置了Nouveau 开源驱动,这是导致频繁死机的直接原因.接下来要做的三件事情是: 禁用Nouveau 内核模块 安装Intel HD 530 驱动(二选一) 安装NVIDIA ...

  5. ssh 常用命令

    1.复制SSH密钥到目标主机,开启无密码SSH登录 ssh-copy-id user@host 如果还没有密钥,请使用ssh-keygen命令生成. 2.从某主机的80端口开启到本地主机2001端口的 ...

  6. 2019.01.16 bzoj3526: [Poi2014]Card(线段树)

    传送门 线段树菜题. 题意:有一些卡牌,正反各有一个数,你可以任意翻转,每次操作会将两张卡牌的位置调换,你需要在每次操作后回答以现在的卡牌顺序能否通过反转形成一个单调不降的序列. 思路: 对于一个线段 ...

  7. Tomcat架构解析(一)-----Tomcat总体架构

    Tomcat是非常常用的应用服务器,了解Tomcat的总体架构以及实现细节,对于理解整个java web也是有非常大的帮助. 一.Server   1.最简单的服务器结构 最简单的服务器结构如图所示: ...

  8. keras backend的修改

    方法一: vim .keras/keras.json 修改“backend”:"tensorflow" 方法二: 每次在python文档中输入, import os os.envi ...

  9. IntelliJ IDEA 2017版 spring-boot2.0.4+mybatis反向工程;mybatis+springboot逆向工程

    一.搭建环境 采用IDE自动建立项目方式 然后,next next,配置导入依赖包 项目就生成了,在项目下导入配置文件GeneratorMapper.xml(项目结构如图所示) 配置文档,建立数据库和 ...

  10. POJ 2433 Landscaping (贪心)

    题意:给定一个序列表示一群山,要你保留最多 K 个山峰,最少要削去多少体积和土.一个山峰是指一段连续的相等的区间,并且左边和右边只能比这个区间低,或者是边界. 析:贪心,每次都寻找体积最小的山峰,然后 ...