【刷题】BZOJ 4946 [Noi2017]蔬菜
Description
http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf
Solution
网上大部分都是并查集写法,但是有大神写了非并查集写法,特别容易理解
首先 \(s_i\) 的限制,只需将每一个蔬菜分出一个价值为 \(a_i+s_i\) 且过期时间为该蔬菜最晚的一天的蔬菜
把时间倒序之后,问题转化为每个蔬菜会在第几天出现,每天贪心选择价值最大的即可
先求出 \(\max \{p_i \}\) 的答案,然后递推 \([1,\max \{pi\}-1]\) 的答案:每次删除价值最小的 \(m\) 单位蔬菜,不难发现所有蔬菜的销售时间依然合法
#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=100000+10,P=100000;
int n,m,k,a[MAXN],c[MAXN],x[MAXN],s[MAXN],vis[MAXN];
ll ans[MAXN],sale[MAXN],tot;
struct node{
ll id,val;
inline bool operator < (const node &A) const {
return val<A.val;
};
inline bool operator > (const node &A) const {
return val>A.val;
};
};
std::vector<int> V[MAXN];
std::queue<node> red;
std::priority_queue<node> q1;
std::priority_queue< node,std::vector<node>,std::greater<node> > q2;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
int main()
{
read(n);read(m);read(k);
for(register int i=1;i<=n;++i)
{
read(a[i]),read(s[i]),read(c[i]),read(x[i]);
if(x[i]==0)V[P].push_back(i);
else V[min(P,(c[i]+x[i]-1)/x[i])].push_back(i);
}
for(register int i=P;i>=1;--i)
{
for(register int j=0,lt=V[i].size();j<lt;++j)q1.push({V[i][j],a[V[i][j]]+s[V[i][j]]});
ll rest=m;
while(!q1.empty()&&rest)
{
node now=q1.top();
q1.pop();
if(vis[now.id])
{
ll res=min(rest,c[now.id]-(i-1)*x[now.id]-sale[now.id]);
ans[P]+=1ll*res*a[now.id];sale[now.id]+=res;rest-=res;
if(sale[now.id]<c[now.id])red.push(now);
}
else
{
vis[now.id]=1;
ans[P]+=now.val;sale[now.id]++;rest--;
if(sale[now.id]<c[now.id])q1.push((node){now.id,a[now.id]});
}
}
while(!red.empty())q1.push(red.front()),red.pop();
}
for(register int i=1;i<=n;tot+=sale[i],++i)
if(sale[i]==1)q2.push((node){i,a[i]+s[i]});
else if(sale[i])q2.push((node){i,a[i]});
for(register int i=P-1;i>=1;--i)
{
ans[i]=ans[i+1];
ll rest=tot-1ll*m*i;
if(rest<=0)continue;
else
while(!q2.empty()&&rest)
{
node now=q2.top();
q2.pop();
if(sale[now.id]==1)sale[now.id]--,rest--,ans[i]-=now.val;
else
{
int res=min(rest,sale[now.id]-1);
sale[now.id]-=res,rest-=res,ans[i]-=1ll*res*now.val;
if(sale[now.id]==1)q2.push((node){now.id,a[now.id]+s[now.id]});
else if(sale[now.id])q2.push((node){now.id,a[now.id]});
}
}
tot=1ll*m*i;
}
for(register int i=1,x;i<=k;++i)read(x),write(ans[x],'\n');
return 0;
}
【刷题】BZOJ 4946 [Noi2017]蔬菜的更多相关文章
- BZOJ.4946.[NOI2017]蔬菜(贪心 离线)
题目链接 因为有删除,考虑倒序处理某个p的询问. 那么每天删除xi的蔬菜就变成了每天运来xi的蔬菜.那么我们取当前最优的即可,早取晚取都一样,不需要留给后面取,还能给后面更优的留出空间. 这样就只需考 ...
- 4946: [Noi2017]蔬菜
4946: [Noi2017]蔬菜 http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf 分析: 贪心. 首先可以将一个蔬菜拆成两个,一个是有加成 ...
- [NOI2017]蔬菜 贪心
题面: [NOI2017]蔬菜 题解: 首先每天蔬菜会变质这点并不好处理,我们考虑让时间倒流,从后向前处理,这样的话就相当于每天都会得到一定量的蔬菜. 这样做有什么好处呢? 我们可以发现一个性质:如果 ...
- 【刷题】BZOJ 2407 探险
Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作人员说明了这次比赛的规则: ...
- 【刷题】BZOJ 4543 [POI2014]Hotel加强版
Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...
- 【刷题】BZOJ 4316 小C的独立集
Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使 ...
- 【刷题】BZOJ 4176 Lucas的数论
Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目"求Sigma(f(i)),其中1<=i< ...
- BZOJ第一页刷题计划
BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...
- 【刷题】BZOJ 2260 商店购物
Description Grant是一个个体户老板,他经营的小店因为其丰富的优惠方案深受附近居民的青睐,生意红火.小店的优惠方案十分简单有趣.Grant规定:在一次消费过程中,如果您在本店购买了精制油 ...
随机推荐
- JAVA程序员必看的15本书-JAVA自学书籍推荐
作为Java程序员来说,最痛苦的事情莫过于可以选择的范围太广,可以读的书太多,往往容易无所适从.我想就我自己读过的技术书籍中挑选出来一些,按照学习的先后顺序,推荐给大家,特别是那些想不断提高自己技术水 ...
- array_sum(),array_product()的使用
这两个函数在你处理数据的时候,相信会很有用处. 一个是处理数组所有值的和,一个是所有值的乘积.写这个随笔就是强调下,有特殊的情况需要注意,以防以后的工作中,统计的时候出现错误. 举个例子: $a = ...
- LCD驱动应该怎么写?–基于stm32F407 [复制链接]
够用的硬件能用的代码使用的教程 (拷贝过来的代码有点乱,请下载附件查看文档) 资料下载地址:https://pan.baidu.com/s/1bHUVe6X6tymktUHk_z91cA 网络上配套S ...
- Base64Util 工具类
package com.org.utils; import java.io.ByteArrayOutputStream; public class Base64Util { private stati ...
- Oracle-归档日志详解(运行模式、分类)
一.Oracle日志分类 分三大类: Alert log files--警报日志,Trace files--跟踪日志(用户和进程)和 redo log 重做日志(记录数据库的更改 ...
- XSS Challenges练习及解答
一个偶然的机会在知道创宇的技能表里看到了一个练习XSS的网站http://xss-quiz.int21h.jp,正好想研究这个,于是试着做了一下. 第一.二题是最简单的,直接在搜索框中输入以下代码就成 ...
- VB 批量重命名文件
VERSION 5.00 Begin VB.Form Form1 BorderStyle = 3 'Fixed Dialog Caption = "Rename use VB QQ 1009 ...
- 20155217《网络对抗》Exp01 PC平台逆向破解(5)M
20155217<网络对抗>Exp01 PC平台逆向破解(5)M 实验要求 掌握NOP,JNE,JE,JMP,CMP汇编指令的机器码 掌握反汇编与十六进制编程器 能正确修改机器指令改变程序 ...
- mfc CAnimateCtrl
知识点: CAnimateCtrl成员函数 播放avi动画 一. CAnimateCtrl成员函数 Autoplay; CAnimateCtrl ::成员函数 Open 打开avi视频 Play 播放 ...
- Android与Libgdx环境配置
此处所说的是基于windows和android版本的libgdx环境配置. 1. 下载所需软件 JDK 1.7. 下载地址: window x86版本地址: http://www.oracle.com ...