HYSBZ-2818: Gcd

来源:互联网 发布:验证java环境变量配置 编辑:程序博客网 时间:2024/04/28 17:45

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为素数)。求结果最后也只是一个模版和2个for循环而已


#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;}