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();
}
posted @ 2025-08-09 23:09  Marinaco  阅读(47)  评论(0)    收藏  举报
//雪花飘落效果