lg8365题解

容易发现我们一定会先加后乘,使用调整法可以证明这个结论。
并且可以发现除了\(a_i\)值为\(1\)的数外(假设他们的\(a\)值和为\(s\)),其他的数最多只会选\(1\)个做加法操作(设如果其他的数都不做加法操作,答案为\(ans\))。并且所有\(a_i=1\)的数都会用加法。使用反证法可以证明
考虑枚举选择的做加法操作的数\(i\)。那么答案为\(ans*\frac{(b_i+s)}{a_i}\)
事实上我们需要找到最大的\(\frac{(b_i+s)}{a_i}\)。使用分数类(维护二元组\((a,b)\)表示\(\frac{a}{b}\)\(a,b\)要开long long)即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mo 1000000007
#define N 1000010
int n,a[N],b[N];
int pw(int x,int y){
	int z=1;
	while(y){
		if(y&1)
			z=z*x%mo;
		x=x*x%mo;
		y>>=1;
	}
	return z;
}
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	for(int i=1;i<=n;i++)
		scanf("%lld",&b[i]);
	int ans=1,v1,v2=1,av,s=1;
	for(int i=1;i<=n;i++){
		if(a[i]==1)
			s+=b[i];
		ans=ans*a[i]%mo;
	}
	av=ans*(s%mo)%mo;
	v1=s;
	for(int i=1;i<=n;i++){
		int va=(ans*pw(a[i],mo-2)%mo*(b[i]+s)%mo)%mo;
		if(a[i]!=1&&(b[i]+s)*v2>a[i]*v1){
			v1=b[i]+s;
			v2=a[i];
			av=va;
		}
	}
	printf("%lld\n",av);
}
posted @ 2023-02-14 16:26  celerity1  阅读(22)  评论(0)    收藏  举报