题解:洛谷P3745 期末考试(整数三分)
题解:洛谷P3745 期末考试(整数三分)
题目大意:给出
操作有两种:
1.让学科 X 的发布时间晚1天,学科 Y 的发布时间早1天,产生A的不愉快度。
2.让学科 Z 的发布时间早1天,产生 B 的不愉快度。
思路:
设
则
考虑三分出最低点(三分的部分就是板子了)
考虑怎么算
操作的不愉快度有两种,一种是 A 的移大补小,一种是 B 的暴力删。
首先明确一点:不关心大的到底补到了哪个小的,小的最终具体时间也不关心,因为同学的不愉快度只跟上限
(1)若
(2)若
当
当
注意三分的边界和退出条件,算
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define F(i,l,r) for(int i=l;i<=r;++i)
const int N=1e5+5;
const ll M=1e16;
int n,m,A,B,a[N],t[N];
ll C,s1[N],s2[N];
inline ll suan(int x){//限制所有学科天数不超过x
ll w1=upper_bound(t+1,t+m+1,x)-t-1,w2=lower_bound(a+1,a+n+1,x)-a-1,
val1=x*w1-s2[w1],val2=(s2[m]-s2[w1])-(m-w1)*x,
res=(w2*x-s1[w2])*C;
//val1:<x的w1天里有多少空缺
//val2:超过x天的学科里要移动多少天过来(或者说理论上要多少空缺)
if(A<B){
if(val1>=val2) return A*val2+res;
else return A*val1+B*(val2-val1)+res;
}
return val2*B+res;
}
int main(){
scanf("%d%d%lld%d%d",&A,&B,&C,&n,&m);
F(i,1,n) scanf("%d",&a[i]); sort(a+1,a+n+1); F(i,1,n) s1[i]=s1[i-1]+a[i];
F(i,1,m) scanf("%d",&t[i]); sort(t+1,t+m+1); F(i,1,m) s2[i]=s2[i-1]+t[i];
if(C==1e16) return printf("%lld",suan(a[1])),0;//特判C很大的情况,不然要开unsigned long long
int l=0,r=t[m]+1,mid1,mid2;
while(l+2<r){
mid1=(2*l+r)/3,mid2=(l+2*r)/3;
if(suan(mid1)>=suan(mid2)) l=mid1;
else r=mid2;
}
printf("%lld",min({suan(l),suan(r),suan(l+1)}));
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】