码迷,mamicode.com
首页 > 其他好文 > 详细

GCD

时间:2017-07-04 12:06:38      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:names   namespace   质数   再处理   std   long   pre   前缀   break   

题目描述

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

输入输出格式

输入格式:

一个整数N

输出格式:

答案

输入输出样例

输入样例#1:
4
输出样例#1:
4

说明

对于样例(2,2),(2,4),(3,3),(4,2)

1<=N<=10^7

首先我们枚举gcd(x,y)=p的p,那么gcd(x/p,y/p)肯定互质,也就是求在[1,n/p](向下取整)范围内的欧拉函数的前缀和,再乘2(因为x和y可以交换),最后再处理一下x是一个质数,gcd(x,x)=x满足题意的情况即可。

直接用欧拉函数线性筛法就行了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 long long phi[10000005],ans;
 8 bool mark[10000005];
 9 int n,tot,prime[5000005];
10 int main()
11 {long long i;
12 long long j;
13     cin>>n;
14     for (i=2;i<=n;i++)
15     {
16         if (mark[i]==0)
17         {
18             prime[++tot]=i;
19             phi[i]=i-1;
20         }
21         for (j=1;j<=tot;j++)
22         {
23             long long k=i*prime[j];
24          if (k>n) break;
25          mark[k]=1;
26          if (i%prime[j]==0)
27          {
28              phi[k]=phi[i]*prime[j];
29              break;
30          }
31          else phi[k]=phi[i]*(prime[j]-1);
32         }
33         phi[i]=phi[i-1]+phi[i]*2;
34     }
35  for (i=1;i<=tot;i++)
36  {
37      ans+=phi[n/prime[i]]+1;
38  }
39  cout<<ans;
40 }

 

GCD

标签:names   namespace   质数   再处理   std   long   pre   前缀   break   

原文地址:http://www.cnblogs.com/Y-E-T-I/p/7115808.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!