$n \leq 100000$种蔬菜,每个蔬菜有:一单位价格;卖第一单位时额外价格;总量;每天腐烂量。每天能卖$m \leq 10$单位蔬菜,多次询问:前$k \leq 100000$天最多收入多少。价格、量$ \leq 1e9$。

我也不知道为啥88分QAQ 求大佬看看啊

把第一单位蔬菜和其他的拆开,记下他们“能卖的最后一天”,假设第一单位蔬菜比其他的要晚卖。这样,按价格排序后,只需要贪心地填入能填的最晚的一天就好了。找最晚的一天用并查集。这样就求出了天数不限时的答案。

要求有限天数内的答案,只需要从天数不限往前推,推的过程中把最便宜的那些丢掉就好了。(可以想象把多出来的空用贵的菜补上)

 //#include<iostream>
#include<cstring>
#include<cstdio>
//#include<math.h>
//#include<set>
//#include<queue>
//#include<bitset>
//#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define LL long long
int qread()
{
char c; int s=,f=; while ((c=getchar())<'' || c>'') (c=='-') && (f=-);
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s*f;
} //Pay attention to '-' , LL and double of qread!!!! int n,m,K;
#define maxn 200011
struct Node{int v,day,tot,c,id; bool operator < (const Node &b) const {return v>b.v;} }p[maxn]; int lp=; int dd[maxn],ufs[maxn];
int find(int x) {return x==ufs[x]?x:(ufs[x]=find(ufs[x]));}
void Union(int x,int y) {x=find(x); y=find(y); if (x!=y) ufs[x]=y;}
//zhu yi da de bing dao xiao de LL ans[maxn]; int list[maxn*],len=;
int main()
{
// freopen("in.txt","r",stdin);
n=qread(); m=qread(); K=qread();
for (int i=;i<=;i++) ufs[i]=i,dd[i]=m;
//我的t是他的c,我的c是他的x。。。。。
for (int i=,a,s,c,t;i<=n;i++)
{
a=qread(); s=qread(); t=qread(); c=qread();
//一种蔬菜拆两种
if (c)
{
p[++lp]=(Node){a+s,t/c+(t%c>),,,i};
if (t>) p[++lp]=(Node){a,(t-)/c+((t-)%c>),t-,c,i};
}
else
{
p[++lp]=(Node){a+s,-,,,i};
if (t>) p[++lp]=(Node){a,-,t-,c,i};
}
}
sort(p+,p++lp); //贪心放,每个蔬菜如果x>0就从“能放的最后一天”开始往前,不然就从100000开始往前放
LL Ans=; int TT=;
for (int i=;i<=lp;i++)
{
int v=p[i].v,day=p[i].day,tot=p[i].tot,c=p[i].c;
// cout<<day<<endl;
LL able=~day?(tot-(day-)*c):0x3f3f3f3f; int now=find(~day?min(day,):); //now 是哪一天,dd 是每天剩多少可以放, tot是这菜还剩多少,able是一个后缀最多放多少菜
//able就是原来总蔬菜量减掉前now-1天的腐烂量剩下的,随着now变小会变大,要排除掉后面已经放了的 while (tot && now)
{
// cout<<able<<' '<<now<<endl;
int can=min(min((LL)tot,able),(LL)dd[now]);
//can是在now这天能放的量
dd[now]-=can; Ans+=can*1ll*v;
if (dd[now]==) Union(now,now-);
int tn=find(now-); able+=1ll*c*(now-tn)-can; now=tn; tot-=can; TT+=can;
for (int j=;j<=can;j++) list[++len]=v;
//list是把真正选中的菜按价格递减放的,偷懒就直接开个大数组丢进去了
}
// cout<<i<<' '<<p[i].v<<' '<<tot<<' '<<p[i].id<<' '<<"ANS"<<Ans<<endl;
// for (int j=1;j<=20;j++) cout<<dd[j]<<' ';cout<<endl<<endl;
} //怀疑上面就错了,用菜总量<=10000的数据算100000天的答案是不对的 //往前推前面的答案
int tmp;
ans[tmp=TT/m+(TT%m>)]=Ans;
// cout<<"tmp"<<tmp<<' '<<"TT"<<TT<<endl;
for (int i=tmp+;i<=;i++) ans[i]=ans[i-];
ans[tmp-]=ans[tmp]; for (int i=TT;i>TT-((TT-)%m+);i--) ans[tmp-]-=list[len--];
for (int i=tmp-;i;i--)
{
ans[i-]=ans[i];
for (int j=;j<=m;j++) ans[i-]-=list[len--];
} for (int i=;i<=K;i++) printf("%lld\n",ans[qread()]);
return ;
}

最新文章

  1. linq 实现动态 orderby
  2. windows端口备忘
  3. PHP--目录处理
  4. 安装GRID时跑root.sh脚本报错(ORA-27091: unable to queue I/O)
  5. ps 简介
  6. 夺命雷公狗ThinkPHP项目之----企业网站14之文章修改页的完成
  7. java内存模型优化建议
  8. LA 3485 (积分 辛普森自适应法) Bridge
  9. 调试中除了在URL上加时间戳外,如何避免js、css被返回304状态?
  10. 【最大流之sap】【HDU1532】模板题
  11. java9最新发布
  12. mybatis04--Mapper动态代理实现
  13. !学习笔记:前端测试 、前端调试、console 等
  14. Java-Runoob-高级教程-实例-时间处理:04. Java 实例 - 时间戳转换成时间
  15. 快速排序中BUG int 与 int *
  16. mybatis启动报错Mapped Statements collection already contains value for com.autoyol.mapper.trans.TransDispatchingMapper解决
  17. There are 2 missing blocks. The following files may be corrupted
  18. basename、dirname、alias、date
  19. CF567F/51nod2522 上下序列
  20. Java并发编程原理与实战四十:JDK8新增LongAdder详解

热门文章

  1. split 分割压缩文件
  2. CentOS7 ngnix 的安装和配置
  3. 认识mysql(2)
  4. (76)zabbix_agentd.conf配置文件详解
  5. js中的日期
  6. 二十五、MySQL 索引
  7. JZOJ 2136. 【GDKOI2004】汉诺塔
  8. 算法_NP_证明
  9. (原创)task和function语法的使用讨论(Verilog,CPLD/FPGA)
  10. P3402 最长公共子序列(nlogn)