牛客周赛round30D题讲解(公式推导)

写的时候题目理解错了(*/ω\*)

登录—专业IT笔试面试备考平台_牛客网

#include 

using ll = long long;

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    ll x, y, l, r;
    std::cin >> x >> y >> l >> r;
    //计算最大公约数
    ll d = std::gcd(x, y);
    //x除以最大公约数
    x /= d;
    //y除以最大公约数
    y /= d;
    ll ansl = std::max((l + x - 1) / x, (l + y - 1) / y);
    ll ansr = std::min(r / x, r / y);
    ll len = std::max(0ll, ansr - ansl + 1);
    std::cout << len;
    return 0;
}

拿一组数据举例,6 36 5 100

首先6和36的gcd为6,所以可以得到的最小的x为1,此时y=6,1*5=5刚好到达边界,而1*4,1*3都不行,紧接着,6*16=96<100,6*15<100……以此类推,所以,最后的结果应该为16-5+1=12,因为5是可以达成目标的,之所以要除以最大公约数是为了拥有更大的操作空间,2*1=2,2*2=4,2*3=6……,如果把2换成4,4*1=4,4*2=8,可以发现,2能达到的4不一定能达到,4不能达到的2一定能达到,那有人就要问了,为什么不会出现3,而一定是2的倍数,可以看到x=n1*k,y=n2*k,k是最大公约数,而x=n1*(p*m),y=n2*(p*m),n1和n2互质我们显然不能变动他们,而变动的k如果不是质数,那么显然它可以分成两个数相乘,所以这就决定了,x和y除以任意一个公因数它们都是除以最大公因数后的倍数,就像这样x=n1,x=n1*p,y=n2,y=n2*p。

这个代码主要的功能就是求x所能到达的所有位置,非常优雅。我刚开始做题的时候理解成只能操作一次,搞半天没搞出来。

 

你可能感兴趣的:(题目讲解,c++)