C++数论—————洛谷P2568 GCD

版权声明:蒟蒻原创博客,大佬转载也需附上链接: https://blog.csdn.net/weixin_43810158/article/details/89144200

题目描述:

给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对。

输入:

一个整数N(1<=N<=10^7)

输出:

答案

输入样例:

4

输出样例:

4

思路分析:

这一题是一个较简单的模板题:

首先,我们先用欧拉筛法,求出1~N的所有质数,

其中我们在欧拉筛法中求出1~N的欧拉函数,而欧拉函数就是1~N-1中与N互质的数。

而我们什么这么求?

相信大家都是知道的:

若在相同的素数上添上两个互质数,那么它们的GCD依旧是那个素数

当然,素数相同的请况需单独处理,就是ans+=p1(质数的个数);

最后,再循环上加欧拉函数时,需要乘2,毕竟是对而不是组。

代码实现:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
ll n,m,pre[5000005],p[10000005],p1,ans;
bool v[10000005];
void olsf()
{
    p[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!v[i])
        {
            v[i]=2;
            p1++;
            pre[p1]=i;
            p[i]=i-1;
        }
        for(int j=1;j<=p1&&i*pre[j]<=n;j++)
        {
            v[i*pre[j]]=1;
            if(i%pre[j]==0)
            {
                p[i*pre[j]]=p[i]*pre[j];
                break;
            }
            p[i*pre[j]]=p[i]*(pre[j]-1);
        }
    }
}
int main()
{
    scanf("%lld",&n);
    olsf();
    ans=p1;
    for(int i=1;i<=p1;i++)
        for(int j=2;j*pre[i]<=n;j++)//此为不超边界。
            ans+=p[j]*2;
    printf("%lld",ans);
}

猜你喜欢

转载自blog.csdn.net/weixin_43810158/article/details/89144200