蓝桥杯小白入门赛第二期 数学尖子生 数学 预定义+容斥

49 阅读2分钟

5.数学尖子生【算法赛】 - 蓝桥云课 (lanqiao.cn)

image.png 观察给的测试样例我们可以发现一个规律:

image.png 总结 image.png code

如果两个数的LCM是 x*y,GCD是 gcd(x,y),那么它们的关系是:x*y/gcd(x,y)=lcm(x,y)。所以,输出的结果就是 n 除以 a-1 的LCM 减去 n 除以 a 的LCM。

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N=1e6+10;

int gcd(int a,int b)
{
    if(b==0)return a;
    else return gcd(b,a%b);
}

int p[N];

signed main()
{
    int t;
    cin>>t;
    
    p[1]=1;
    for(int i=2;i<=N;i++)//预处理
    {
        p[i]=i*p[i-1]/gcd(i,p[i-1]);//lcm(a,b)=a*b/gcd(a,b)
        if(p[i]>1e16)
        {
            p[i]=0;
            break;//后续公倍数均大于1e16,直接退出
        }
    }
    
    while(t--)
    {
        int a,n;
        cin>>a>>n;
        
        if(a==1)cout<<0<<endl;//不存在因数没有1的数
        else
        {
            if(p[a-1]==0)cout<<0<<endl;
            else if(p[a]==0)cout<<n/p[a-1]<<endl;
            else cout<<n/p[a-1]-n/p[a]<<endl;
        }
    }
    
    return 0;
}

这三行代码是if-else语句的一部分。它们用于计算并输出给定数字'a'在1到'n'范围内的倍数数量。

  1. if(a==1)cout<<0<<endl; - 这行代码检查给定的数字'a'是否等于1。如果是,那么意味着在1到'n'范围内没有1的倍数,因此输出0。

  2. else if(p[a-1]==0)cout<<0<<endl; - 如果'a'不等于1,则检查p[a-1]的值是否为0。如果是,那么意味着在1到'n'范围内没有'a-1'的倍数,因此输出0。

  3. else if(p[a]==0)cout<<n/p[a-1]<<endl; - 如果以上条件都不成立,则检查p[a]的值是否为0。如果是,那么意味着在1到'n'范围内没有'a'的倍数,因此输出1到'n'范围内'a-1'的倍数数量。

  4. else cout<<n/p[a-1]-n/p[a]<<endl; - 如果以上条件都不成立,则通过从'a'的倍数数量中减去'a-1'的倍数数量来计算1到'n'范围内'a'的倍数数量,然后输出结果。