题解 P3745 【[六省联考2017]期末考试】
看了看楼下题解好多都是三分大佬+一堆函数的分析qwq
注意到本题有一个特点,学生的不愉快度只与最晚公布成绩的时间有关
看看题目数据范围,ti,bi<=10^5
所以很自然地想到一种思路
枚举最晚公布成绩的时间
假设我们当前枚举的最晚公布时间为t,那么我们显然要把所以大于t的课程公布时间调为t即可。
此时根据A与B的关系分类讨论:
若A>B 显然将大于t的课程全部使用操作2调为t更优
若A<B 显然能使用操作1则使用,当不能使用(公布时间小于t的课程全部因操作1导致公布时间推迟到t)时,只能将剩下大于t的课程使用操作2处理
A=B随意
对于C,因为最晚公布时间为t,统计一下对不愉快度的贡献即可
具体实现用3个前缀和,对所有情况取min
时间复杂度O(max(bi)) 我是直接从10^5开始枚举的
这种做法不开unsigned long long 居然会挂两个点qwq
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=100000+5;
typedef unsigned long long ll;
const ll inf=100000000000000000ll;
ll bac[N],bac2[N],ti[N],bi[N],A,B,C,n,m;
int main(){
scanf("%lld%lld%lld",&A,&B,&C);
scanf("%lld%lld",&n,&m);
ll sum1=0,t1=0,sum2=0,t2=0,sum3=0,t3=0;
for(int i=1;i<=n;i++)
scanf("%lld",&ti[i]),bac2[ti[i]]++,sum3+=ti[i],t3++;
for(int i=1;i<=m;i++)
scanf("%lld",&bi[i]),bac[bi[i]]++,sum2+=bi[i],t2++;
ll ans=inf;
for(ll i=100000;i>=1;i--){
sum1+=i*bac[i],t1+=bac[i];
sum2-=i*bac[i],t2-=bac[i];
sum3-=i*bac2[i],t3-=bac2[i];
if(!sum1)continue;
ll tep=0;
if(A<B){
ll LQ1=sum1-t1*i,LQ2=t2*i-sum2;
tep+=min(LQ1,LQ2)*A;
LQ1-=min(LQ1,LQ2);
if(LQ1)tep+=LQ1*B;
}
else {
ll LQ1=sum1-t1*i;
tep+=LQ1*B;
}
tep+=(t3*i-sum3)*C;
ans=min(ans,tep);
}
cout<<ans;
return 0;
}