分析
我们知道如果设A,B分别为将两家店从大到小排序之后各自的前缀和,则
Ans=Max{Min{A[i],B[j]}-W*(i+j)}。
为了得到这个Ans我们可以枚举两个数的Min,然后剩下那一个则使用二分求出在另一数列中大于Min的中最小的,这样的原因是为了使得W*(i+j)更小,从而在可能情况下达到最优。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
long long a[100100],b[100100];
int main(){
long long n,m,i,j,k,w,Ans=0;
scanf("%lld%lld",&n,&w);
for(i=1;i<=n;i++)scanf("%lld",&a[i]);
for(i=1;i<=n;i++)scanf("%lld",&b[i]);
reverse(a+1,a+n+1);
reverse(b+1,b+n+1);
for(i=1;i<=n;i++)a[i]=a[i-1]+a[i];
for(i=1;i<=n;i++)b[i]=b[i-1]+b[i];
for(i=1;i<=n;i++){
long long x=lower_bound(b+1,b+n+1,a[i])-b;
if(x<=n)Ans=max(Ans,a[i]-w*(i+x));
}
for(i=1;i<=n;i++){
long long x=lower_bound(a+1,a+n+1,b[i])-a;
if(x<=n)Ans=max(Ans,b[i]-w*(i+x));
}
printf("%lld
",Ans);
return 0;
}