BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流
题目链接:
题目大意:有$n$种蔬菜,每种蔬菜有$c_{i}$个,每种蔬菜每天有$x_{i}$个单位会坏掉(准确来说每天每种蔬菜坏掉的量是$x_{i}-$当天这种蔬菜卖出量),每卖出一个单位的蔬菜获得收益为$a_{i}$,第一次卖出一种蔬菜会得到$s_{i}$的额外收益,限制每天最多卖出$m$个单位的蔬菜,有$k$次询问,每次询问卖$p_{i}$天的最大收益。
因为每种蔬菜坏掉的部分是固定的,那么我们可以将每种蔬菜分成$\frac{c_{i}-1}{x_{i}}+1$类,第$i$类在第$i$天坏掉。那么对于本题就可以建出费用流模型:源点向每一天连边,容量为$m$,费用为$0$;第$i$天向第$i+1$天连边,容量为$INF$,费用为$0$;每一天向每种蔬菜这一天坏掉的那类连边,容量为这一类的数量,费用为$0$;每一类蔬菜向汇点连边,容量为这一类的数量,费用为$a_{i}$。最后在最后一天每一种蔬菜中取出一个容量新建一个点连向汇点,容量为$1$,费用为$a_{i}+s_{i}$。这样直接跑费用流会有$60pts$。我们观察一下这个图的特殊性质:只有蔬菜向汇点连的边有费用。因为每次增广一定是选取最长路,那么每次增广的路径就一定不会走有费用的反向边(即不会退流)。这也就说明对于$p=i$时选取的蔬菜一定是$p=i-1$时选取的蔬菜的父集(多选的那部分就是最便宜的那$m$个蔬菜)。那么我们可以模拟这个费用流的过程——每次选择当前能选的蔬菜中权值最大的。为了使当前的选择是可行的,设$f[i]$为在第$i$天及之前过期的蔬菜选取量,那么我们就要保证$\forall i,f[i]-i*m<=0$,即$max(f[i]-i*m)<=0$,这个东西我们用线段树来维护即可。那么我们现在的问题就是如何要让当前权值最大的蔬菜尽可能的多选,因为选择第$i$天过期的蔬菜会将所有$i\le j$的$f[j]$都$+1$。那么如果不能选后过期的就一定不能选先过期的,而不能选先过期的可能还能选后过期的,所以我们每次贪心地先选后过期的那部分。如果一次选择使$masx(f[i]-i*m)>0$,说明这种蔬菜剩下的都过期了,那么就撤销这次操作并在以后都不选这种蔬菜。那么我们只要用堆维护所有种类的蔬菜然后从第一天开始,每天贪心地选$m$个蔬菜并记录每天的答案在最后统一输出即可。特别注意$x_{i}=0$的蔬菜看作都在最后一天过期。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define pr pair<int,int>
#define lim 100010
using namespace std;
int c[100010];
int a[100010];
int s[100010];
int x[100010];
int n,m,k,z;
ll ans[100020];
priority_queue<pr>q;
int mx[400010];
int sum[400010];
ll res;
void pushup(int rt)
{
mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
}
void pushdown(int rt)
{
if(sum[rt])
{
sum[rt<<1]+=sum[rt];
sum[rt<<1|1]+=sum[rt];
mx[rt<<1]+=sum[rt];
mx[rt<<1|1]+=sum[rt];
sum[rt]=0;
}
}
void build(int rt,int l,int r)
{
if(l==r)
{
mx[rt]=-l*m;
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
void change(int rt,int l,int r,int L,int R,int v)
{
if(L<=l&&r<=R)
{
mx[rt]+=v;
sum[rt]+=v;
return ;
}
pushdown(rt);
int mid=(l+r)>>1;
if(L<=mid)
{
change(rt<<1,l,mid,L,R,v);
}
if(R>mid)
{
change(rt<<1|1,mid+1,r,L,R,v);
}
pushup(rt);
}
bool judge(int id)
{
int t=x[id]?(c[id]-1)/x[id]+1:lim;
change(1,1,lim,t,lim,1);
if(mx[1]<=0)
{
return 1;
}
change(1,1,lim,t,lim,-1);
return 0;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&a[i],&s[i],&c[i],&x[i]);
q.push(make_pair(a[i]+s[i],i));
}
build(1,1,lim);
for(int i=1;i<=lim;i++)
{
int num=m;
while(num&&!q.empty())
{
int v=q.top().first;
int id=q.top().second;
q.pop();
if(!judge(id))continue;
res+=v,num--,c[id]--;
if(c[id])
{
q.push(make_pair(a[id],id));
}
}
ans[i]=res;
}
while(k--)
{
scanf("%d",&z);
printf("%lld\n",ans[z]);
}
}
BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流的更多相关文章
- 【BZOJ3252】攻略 DFS序+线段树(模拟费用流)
[BZOJ3252]攻略 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏. 今天他得到了一款新游戏<XX半岛> ...
- BZOJ4977[Lydsy1708月赛]跳伞求生——贪心+堆+模拟费用流
题目链接: 跳伞求生 可以将题目转化成数轴上有$n$个人和$m$个房子,坐标分别为$a_{i}$和$b_{i}$,每个人可以进一个他左边的房子,每个房子只能进一个人.每个房子有一个收益$c_{i}$, ...
- [UOJ455][UER #8]雪灾与外卖——堆+模拟费用流
题目链接: [UOJ455]雪灾与外卖 题目描述:有$n$个送餐员(坐标为$x_{i}$)及$m$个餐厅(坐标为$y_{i}$,权值为$w_{i}$),每个送餐员需要前往一个餐厅,每个餐厅只能容纳$c ...
- BZOJ4946 NOI2017蔬菜(贪心+堆)
容易想到一个费用流做法:将每种蔬菜拆成p种,对应p个过期时间,每一种向可以卖的时间连边,第一次卖的奖励算在最晚过期的一种里.对于天数动态加点.不过这样边数太多了,因为第i天能卖的第i-1天一定能卖,可 ...
- 模拟费用流 & 可撤销贪心
1. CF730I Olympiad in Programming and Sports 大意: $n$个人, 第$i$个人编程能力$a_i$, 运动能力$b_i$, 要选出$p$个组成编程队, $s ...
- 【CF280D】 k-Maximum Subsequence Sum ,线段树模拟费用流
昨天考试被教育了一波.为了学习一下\(T3\)的科技,我就找到了这个远古时期的\(cf\)题(虽然最后\(T3\)还是不会写吧\(QAQ\)) 顾名思义,这个题目其实可以建成一个费用流的模型.我们用流 ...
- Codeforces 280D k-Maximum Subsequence Sum [模拟费用流,线段树]
洛谷 Codeforces bzoj1,bzoj2 这可真是一道n倍经验题呢-- 思路 我首先想到了DP,然后矩阵,然后线段树,然后T飞-- 搜了题解之后发现是模拟费用流. 直接维护选k个子段时的最优 ...
- 【BZOJ3638】Cf172 k-Maximum Subsequence Sum 线段树区间合并(模拟费用流)
[BZOJ3638]Cf172 k-Maximum Subsequence Sum Description 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交 ...
- 【bzoj3638】Cf172 k-Maximum Subsequence Sum 模拟费用流+线段树区间合并
题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...
随机推荐
- 吉特日化MES-日化生产称料基本步骤
在日化行业称料是一个非常重要的环节,整个生产过程中称料所占据的时间也比较长,特别是遇到对料体精度高,量大的情况下称料都比较困难,汇总一下人工称料的基本过程: (1) 称量任务准备:根据生产工单或者生产 ...
- ReactJs移动端兼容问题汇总
汽车H5使用ReactJs问题汇总 Q:安卓4.4webview显示空白? A:初步怀疑是css属性没有加前缀引发的兼容问题,但添加后发现也不行,通过webview调试后控制台输出Set is und ...
- Git_GitHub详解
Git和Github详细教程 一 概述 说到Git和Github,前几天我们知道微软以75亿美元收购全球最大的代码托管和写作平台GitHub,而GitHub是全球最大的代码仓库,很多开发人员都将代码 ...
- OSS网页上传和断点续传(OSS配置篇)
OSS网页上传和断点续传主要根据BrowserJS-SDK和相关文档整理而得,快速构建OSS上传应用 一.Bucket设置 浏览器中直接访问OSS需要开通Bucket的CORS设置 将allowed ...
- 关于 pip安装的可能错误的排除
今天安装selenium总是报错(下为错误信息) C:\Python27\Scripts>pip install seleniumCollecting seleniumC:\Python27\l ...
- httpd.conf简单配置
本文介绍apache中httpd.conf的配置.该配置也可解决打开php文件却变成下载的尴尬情况 1 修改网站根目录查找DocumentRoot有这么一行DocumentRoot "C:/ ...
- 开发环境搭建(lnmp)
我们的开发环境一般现在时用Linux + Nginx + MySQL(mariaDB) + PHP的组合进行项目的搭建与开发,工欲善其事必先利其器. 搭建环境: Centos7 + mysql5.6 ...
- JMeter学习non-gui模式运行
-h, --help print usage information and exit #打印帮助信息 -v, --version print the version information and ...
- MyEclipse 配置 Tomcat
安装好Tomcat,MyEclipse 之后,利用这两个工具可以开发部署Web 应用,步骤相对手动部署要简洁的多,这里有一个特别要注意的地方:系统里安装JDK.Tomcat.MyEclipse 的版本 ...
- Errors running builder 'DeploymentBuilder' on project
Errors running builder 'DeploymentBuilder' on project 1.修改java源代码后点击保存,IDE 自动编译并热部署,提示如下错误: Errors o ...