【bzoj2818】Gcd

来源:互联网 发布:宋为什么灭大理知乎 编辑:程序博客网 时间:2024/05/29 08:16

Description
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
Input
一个整数N
Output
如题
Sample Input
4
Sample Output
4
HINT
对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7

题解:
首先求出phi的值,然后做一个前缀和。
然后枚举小于n的每一个质数。
所有<=n/p[i]的互质的两个数乘上p[i]都小于n且gcd为p[i];
因为已经做前缀和所以直接加上phi[n/p[i]]*2-1即可。

代码

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#define N 10001#define M 1000001#define ll long longll sum[10000005],ans;bool mark[10000005];int phi[10000005],p[10000005];int n,tot;using namespace std;inline int read(){    int x=0;char ch=getchar();    while (ch<'0'||ch>'9') ch=getchar();    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x;}int main(){    n=read();phi[1]=1;    for (int i=2;i<=n;i++)    {        if (!mark[i]) phi[i]=i-1,p[++tot]=i;        for (int j=1;j<=tot&&i*p[j]<=n;j++)        {            mark[i*p[j]]=1;            if (i%p[j]==0)            {                phi[i*p[j]]=phi[i]*p[j];                break;             }            phi[i*p[j]]=phi[i]*(p[j]-1);        }    }    for (int i=1;i<=n;i++)        sum[i]=sum[i-1]+phi[i];    for (int i=1;i<=tot;i++)        ans+=sum[n/p[i]]*2-1;    printf("%lld",ans);    return 0; }
0 0
原创粉丝点击