2025杭电暑期多校第七场(持续更新)
1006
题意:给出若干参数,请求出x([L,R]范围内),使得表达式值最大
思路:
设题目所给的N/K为m
那么f(x)=x/(m/x)(向下取整)+x
如果x>m,那么f(x)=x,此时x越大越好,若R>m,那么一个答案为f(R)=R
如果x=m,那么f(x)=2x=2m
如果x<m,那么由于向下取整函数存在,x取1/p个m时最好(p>1)
举个例子当p=2时,答案为3/2个m,此时攻击次数为2次,攻击力x为1/2个m
当p=5/2时,答案为6/5个m,此时攻击次数为2次,而攻击力x为2/5个m
当p=3时,答案为4/3个m,此时攻击次数为3次,而攻击x为1/3个m
显然在x取1/p个m时,攻击次数恰好发生改变,因此f(x)的函数形状像一堆不连续的上升直线
x=1/p为不连续点,f(x)=(p+1)/p个m, p越大f(x)越大
可以考虑二分p,求第一个满足<=R且>L的p
并且这道题需要用到分数类
struct Frac{
int u,d;
Frac(){}
Frac(int a,int b){u=a;d=b;}
void show(){
int g = __gcd(u,d);
cout<<u/g<<'/'<<d/g<<endl;
}
bool operator<= (const Frac&t){
return u*t.d<=d*t.u;
}
bool operator>= (const Frac&t){
return u*t.d>=d*t.u;
}
bool operator> (const Frac&t){
return u*t.d>d*t.u;
}
};
void solve(){
int k,n,a,b,c,d;cin>>k>>n>>a>>b>>c>>d;
Frac times(k,n),L(a,b),R(c,d);
Frac ans(((k*d/(n*c))+1)*c,d);
int l=1,r=1e9;
int res=0;
while(l<=r){
int mid = l+r>>1;
if(Frac(k,n*mid)>R){
l=mid+1;
}else{
r=mid-1;
if(Frac(k,n*mid)>=L)res=mid;
}
}
if(res){
if(ans<=(Frac((res+1)*k,res*n))){
ans=Frac((res+1)*k,n*res);
}
}
ans.show();
}

浙公网安备 33010602011771号