UOJ#318. 【NOI2017】蔬菜 贪心
原文链接 www.cnblogs.com/zhouzhendong/p/UOJ318.html
前言
我怎么越来越菜了。
题解
首先,对于一个物品,我们将它拆成若干份:最后一天拆成两份,一份的个数为1 ,价值为 a+s;另一份的个数为 (c-1) mod x,价值为 a。对于在 $(c-1) / x $ 天以及以前,每天有一份个数为 x,价值为 a 的物品。
于是,用堆维护物品,每次取最大价值的,就可以在 \(O(n ^ 2 m \log n)\) 的时间复杂度内得到一个询问的答案。
考虑将所有物品分成两种:
- 这种物品个数为 x,价值为 v 。
- 这种物品个数为 x,价值为 v,而且每天又会凭空多出 x 个。
然后同样用堆维护,可以做到 \(O(n m\log n)\) 回答单次询问。
如果我们得到了 \(k\) 天的答案,那么我们只需要扔掉价值最小的一些物品,使得剩余物品数 \(\leq (k-1) m\) ,就可以得到 \(k-1\) 天的答案。
于是我们只需要算出 100000 天的答案,然后倒推,即可预处理出所有询问的答案。
总时间复杂度 \(O(nm\log n+ k)\)。
代码
#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof x)
#define For(i,a,b) for (int i=(a);i<=(b);i++)
#define Fod(i,b,a) for (int i=(b);i>=(a);i--)
#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define outval(x) cerr<<#x" = "<<x<<endl
#define outtag(x) cerr<<"---------------"#x"---------------"<<endl
#define outarr(a,L,R) cerr<<#a"["<<L<<".."<<R<<"] = ";\
For(_x,L,R)cerr<<a[_x]<<" ";cerr<<endl;
using namespace std;
typedef long long LL;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=100005;
int n,m,k;
int lim=1e5;
struct Node{
int type,T;
LL x;
int v,X;
Node(){}
Node(int _t,int _x,int _v){
type=_t,x=X=_x,v=_v;
}
friend bool operator < (Node a,Node b){
return a.v<b.v;
}
};
vector <Node> A[N];
priority_queue <int,vector <int>,greater <int> > Q;
priority_queue <Node> q;
vector <Node> tmp;
LL res[N];
int main(){
n=read(),m=read(),k=read();
For(i,1,lim)
A[i].clear();
For(i,1,n){
int a=read(),s=read(),c=read(),x=read();
if (!c)
continue;
if (x>0){
int las=c/x+1,rem=c%x;
if (rem==0)
las--,rem=x;
las=min(las,lim-1);
A[las].pb(Node(0,1,a+s));
A[las].pb(Node(0,rem-1,a));
A[las-1].pb(Node(1,x,a));
}
else {
A[lim].pb(Node(0,1,a+s));
A[lim].pb(Node(0,c-1,a));
}
}
LL ans=0;
Fod(i,lim,1){
for (auto v : A[i]){
Node vv=v;
vv.T=i;
q.push(vv);
}
tmp.clear();
For(cc,1,m){
if (q.empty())
break;
Node now=q.top();
q.pop();
if (now.T>i&&now.type==1)
now.x+=(LL)(now.T-i)*now.X,now.T=i;
if (now.x==0){
if (now.type==1)
tmp.pb(now);
cc--;
continue;
}
ans+=now.v;
Q.push(now.v);
now.x--;
q.push(now);
}
while (!tmp.empty())
q.push(tmp.back()),tmp.pop_back();
}
Fod(i,lim,1){
res[i]=ans;
while (Q.size()>m*(i-1)){
ans-=Q.top();
Q.pop();
}
}
while (k--)
printf("%lld\n",res[read()]);
return 0;
}
UOJ#318. 【NOI2017】蔬菜 贪心的更多相关文章
- [NOI2017]蔬菜 贪心
题面: [NOI2017]蔬菜 题解: 首先每天蔬菜会变质这点并不好处理,我们考虑让时间倒流,从后向前处理,这样的话就相当于每天都会得到一定量的蔬菜. 这样做有什么好处呢? 我们可以发现一个性质:如果 ...
- NOI2017蔬菜(贪心)
小 N 是蔬菜仓库的管理员,负责设计蔬菜的销售方案. 在蔬菜仓库中,共存放有 n 种蔬菜,小 N 需要根据不同蔬菜的特性,综合考虑各 方面因素,设计合理的销售方案,以获得最多的收益. 在计算销售蔬菜的 ...
- BZOJ.4946.[NOI2017]蔬菜(贪心 离线)
题目链接 因为有删除,考虑倒序处理某个p的询问. 那么每天删除xi的蔬菜就变成了每天运来xi的蔬菜.那么我们取当前最优的即可,早取晚取都一样,不需要留给后面取,还能给后面更优的留出空间. 这样就只需考 ...
- 【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}-$当天这种蔬菜卖出量), ...
- 4946: [Noi2017]蔬菜
4946: [Noi2017]蔬菜 http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf 分析: 贪心. 首先可以将一个蔬菜拆成两个,一个是有加成 ...
- uoj318 [NOI2017]蔬菜 【贪心 + 堆 + 并查集】
题目链接 uoj 题解 以前看别人博客,在考场上用费用流做,一直以为这题是毒瘤网络流题 没想到竟然是贪心模拟题... 如果只有一个蔬菜呢?这就是一个经典的普及难度的贪心,正着推面临优先选择的困难,而逆 ...
随机推荐
- (转)项目迁移_.NET项目迁移到.NET Core操作指南
原文地址:https://www.cnblogs.com/heyuquan/p/dotnet-migration-to-dotnetcore.html 这篇文章,汇集了大量优秀作者写的关于" ...
- element-ui DatePicker 日期格式处理
1.使用DatePicker 日期选择器得到的日期格式是这样的 解决方案,添加 value-format="yyyy-MM-dd" <el-date-picker type= ...
- Qt 窗口相关的常用操作
PS: 本文使用的是Qt 4.8.4版本,不同版本代码可能会有差异 设置窗口标题 setWindowTitle(QString::fromLocal8Bit("易语言")); 禁用 ...
- linux之expect用法
1. [#!/usr/bin/expect] 这一行告诉操作系统脚本里的代码使用那一个shell来执行.这里的expect其实和linux下的bash.windows下的cmd是一类东西. 注意:这一 ...
- 腿部——哑铃&杠铃
- Android笔记(六十六) android中的动画——XML文件定义属性动画
除了直接在java代码中定义动画之外,还可以使用xml文件定义动画,以便重用. 如果想要使用XML来编写动画,首先要在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在 ...
- Linux kernel启动选项(参数)
在Linux中,给kernel传递参数以控制其行为总共有三种方法: 1.build kernel之时的各个configuration选项. 2.当kernel启动之时,可以参数在kernel被GRUB ...
- 编译制作Linux 3.18内核rpm包(升级centos6.x虚拟机内核)
介绍 openstack平台需要使用各种Linux发行版模板镜像,其制作方法主要有两种,要么是基于各大Linux发行版ISO光盘手动制作,要么是使用官方提供的模板镜像再做修改 之前制作的opensta ...
- Django中多对多关系的orm表设计
作者的管理 1.设计表结构 出版社 书籍 作者 一个出版社出版多个书籍 1对多 书籍和作者的关系:一个作者写多本书,一本书可以是多个作者写.多对多 1)创建一张表,表中多对多的数据关系.使用 多对多 ...
- 行为型模式(七) 策略模式(Stragety)
一.动机(Motivate) 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂:而且有时候支持不使用的算法也是一个性能负担.如何在运行时 ...