您的位置:首页 > 其它

HYSBZ-2818: Gcd

2017-08-24 10:04 393 查看

2818: Gcd

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 6160  Solved: 2725
[Submit][Status][Discuss]

Description

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

Input

一个整数N

Output

如题

Sample Input

4

Sample Output

4

HINT

hint

对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7

思路:莫比乌斯简单应用。可以参考http://www.cnblogs.com/chenyang920/p/4811995.html
弄懂之后,就是求GCD(x/p,y/p)==1的对数,p就是x,y的最大公约数(p为素数)。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int MAX=1e7+5;
int all;
int phi[MAX]; //欧拉函数
int u[MAX]; //莫比乌斯系数表
int d[MAX]; //d[i]=i的因子个数
int isp[MAX]; //是否是素数
int pr[MAX]; //素数表
void init()
{
u[1]=phi[1]=d[1]=1;
all=0;
for(int i=2;i<=MAX;i++)
{
if(!isp[i])
{
pr[all++]=i;
u[i]=-1;
phi[i]=i-1;
isp[i]=i;
d[i]=2;
}
for(int j=0;j<all&&i*pr[j]<=MAX;j++)
{
if(i%pr[j]==0)
{
u[i*pr[j]]=0;
phi[pr[j]*i]=phi[i]*pr[j];
isp[i*pr[j]]=isp[i]*pr[j];
d[i*pr[j]]=d[i/isp[i]]*(d[isp[i]]+1);
break;
}
u[i*pr[j]]=-u[i];
phi[pr[j]*i]=phi[i]*(pr[j]-1);
isp[i*pr[j]]=pr[j];
d[i*pr[j]]=2*d[i];
}
}
}
int main()
{
init(); //模版
int n;
while(scanf("%d",&n)!=EOF)
{
long long ans=0;
for(int j=0;j<all&&pr[j]<=n;j++)
{
for(int i=1;i<=n/pr[j];i++)ans+=(long long)u[i]*(n/pr[j]/i)*(n/pr[j]/i);
}
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: