版权声明:蒟蒻原创博客,大佬转载也需附上链接: 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);
}