我太菜了,QAQ
Luogu
简要分析
和洛谷的一篇分治的题解是一样的想法(是我看的她的),我只是一个更详细的代码解释,所以大家还是看洛谷题解吧
简要说一下。贪心的选取。在C花费多的情况下,若A比B花费多,就一直用B,否则就用A。同理,若C花费少,就用C。
其次是贪心的判断。选取时间点,看一看把所有的成绩都提升至该时间点的是否可以。
所有的见代码吧
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1e5+10;
unsigned long long t[maxn],d[maxn],used[maxn];
unsigned long long c[maxn],up[maxn],n,m,A,B,C;
//t[i]->时间上线为i的数目
unsigned long long flag,yes,last,x,ans;
inline void prework(){
long long val=0,tot=0;
if(flag!=3)//如果不是C大到离谱
for(register int i=1;i<=last;i++)
val+=tot*C,tot+=t[i],c[i]=val;
//统计C的结果看一看到i这个时间点不满值是多少
val=0;tot=0;
for(register int i=1;i<=last;i++)
val+=tot,tot+=d[i],used[i]=val;
//看如果把时间线强行提到d[i],最多可以进行几次A
val=0;tot=0;
for(register int i=last;i>=1;i--)
val+=tot,tot+=d[i],up[i]=val;
//看如果把时间线强行提到d[i],最多要进行几次提升
}
inline void work(){
//不用B的点
long long now;ans=c[last];
//如果一次提升也不进行,ans一直都是c[last]
for(register int i=last;i>=1;i--){
now=c[i];//枚举最后一天
if(used[i]>=up[i]) now+=up[i]*A;
//如果这个点要提升的次数大于最多可以用A提升的次数
//那你就无能为力了,所以此时直接退出
else break;
ans>now?ans=now:ans=ans;
}
}
inline void work1(){
ans=0ll;long long QAQ=0;
//只用A,B的点,不能让学生等,
//所以找到第一个有不满意值的时候,把所有的都提升到这个时候之前就好
for(register int i=1;i<=last;i++)
if(t[i]){QAQ=i;break;}//首先找到一个需要提升的点
//即这个点有不满意值
if(yes)//如果B>A 就先用A
if(used[QAQ]>=up[QAQ]) ans+=up[QAQ]*A;
//如果A还可以再用一会儿
else ans+=used[QAQ]*A+(up[QAQ]-used[QAQ])*B;
//当A用完了的时候,就只用B
else ans+=up[QAQ]*B;
//如果干脆A就B大,就只用B
}
inline void work2(){
//毫无特色的点
long long now;ans=c[last];
for(register int i=last;i>=1;i--){
now=c[i];
if(yes)
if(used[i]>=up[i]) now+=up[i]*A;
else now+=used[i]*A+(up[i]-used[i])*B;
else now+=up[i]*B;
ans>now?ans=now:ans=ans;
}
//毫无特色的注释
}
int main(){
scanf("%llu%llu%llu%llu%llu",&A,&B,&C,&n,&m);
for(register int i=1;i<=n;i++) scanf("%llu",&x),t[x]++;
for(register int i=1;i<=m;i++)
scanf("%llu",&x),last=max(x,last),d[x]++;
if(B>A) yes=1;
if(A==1e9&&B==1e9) flag=1;
else if(A!=1e9&&B==1e9) flag=2;
else if(C==1e16) flag=3;
prework();
if(flag==1) printf("%llu",c[last]);
else if(flag==2) work();
else if(flag==3) work1();
else work2();printf("%llu",ans);
//毫无特色的主函数(除了压行)
}