BZOJ2818 欧拉函数

题意:求1--n中满足gcd(x,y)的值为质数的数对(x,y)的数目  ( (x,y)和(y,x)算两个 )

sol:

设p[i]是一个质数,那么以下两个命题是等价的:

1.gcd(x,y)=1

2.gcd(x*p[i],y*p[i])=p[i]

eg:gcd(36,25)=1,gcd(36*7,25*7)=7

所以对于1--n的所有质数p[i],求一下1<=x,y<=n/p[i]中所有gcd(x,y)=1的数对的数目即可。

如何求1--r范围内所有互质数对的数目?

考虑欧拉函数φ(x)=1..x中与x互质的数的数目

设x<=y,那么这样就可以求出来了:

for y:=2 to r do    //1不是质数也不是合数,而且1和任意数的gcd都等于1,应该除去
  ans+=2*phi[y];           //(x,y)和(y,x)算两个
ans++;    //这是本题的特殊情况:当x==y时,gcd(y,y)的值也是质数

Solve函数是题解里用的,事先累加了所有2*phi[i],速度要快一点点

Reference: http://blog.csdn.net/acdreamers/article/details/8542292

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cmath>
 4 using namespace std;
 5 #define LL long long
 6 #define MMX 10000010
 7 int phi[MMX],p[MMX];
 8 LL psum[MMX];
 9 bool pr[MMX];
10 LL nm,ret,n;
11
12 void calc_phi(int n)        //求1--n的欧拉函数,phi[i]
13 {                           //psum[n]:sum of phi[1..n]*2
14     for (int i=2;i<=n;i++)
15         phi[i]=0;
16     phi[1]=1;
17     for (int i=2;i<=n;i++)
18         if (!phi[i])
19             for (int j=i;j<=n;j+=i)
20             {
21                 if (!phi[j])    phi[j]=j;
22                 phi[j]=phi[j]/i*(i-1);
23             }
24     psum[1]=0;
25     for (int i=2;i<=n;i++)
26         psum[i]=psum[i-1]+phi[i]*2;
27 }
28
29 void isprime(LL n)     //求1--n的质数。pr[i]=1 : i is a prime
30 {
31     nm=0;
32     memset(pr,true,sizeof(pr));
33     LL m=sqrt(n+0.5);
34     pr[1]=false;
35     for (LL i=2;i<=m;i++)
36         if (pr[i])
37         {
38             for (LL j=i*i;j<=n;j+=i)
39                 pr[j]=false;
40         }
41     for (int i=1;i<=n;i++)
42         if (pr[i])
43         {
44             nm++;
45             p[nm]=i;
46         }
47 }
48
49 LL Solve(int n)     //
50 {
51     LL ans = 0;
52     for(int i=1; i<=nm&&p[i]<=n; i++)
53         ans += 1 + psum[n/p[i]];
54     return ans;
55 }
56
57 int main()
58 {
59     cin>>n;
60     isprime(n);
61     calc_phi(n);
62
63     LL ret=0;
64     for (int i=1;i<=nm;i++)
65     {
66         int r=n/p[i];
67         for (int j=2;j<=r;j++)  //注意1不能包括进去,因为gcd(1,?)恒等于1
68             ret+=2*phi[j];
69         ret++;
70     }
71     cout<<ret<<endl;
72
73     //cout<<endl<<Solve(n)<<endl;
74     return 0;
75 }
时间: 2024-11-09 02:21:28

BZOJ2818 欧拉函数的相关文章

[BZOJ2818] Gcd (数论,欧拉函数,线性筛)

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2818 必须用线性筛. 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 10001001; 5 LL phi[maxn], sum[maxn], n; 6 bool isprime[maxn]; 7 LL prime[maxn]; 8 int tot;

BZOJ2818 GCD 【欧拉函数,线性筛】

题目大意: 给一个范围[1,n],从中找出两个数x,y,使得gcd(x,y)为质数,问有多少对(x,y有序) 解法: 不难,欧拉函数练手题,可以定义集合P ={x|x为素数},那么我们枚举gcd(x,y)可能等于的情况,对于任意p∈P可以得到:gcd(k1·p,k2·p) = p,当且仅当gcd(k1,k2) =1;那么我们就只需要枚举所有的k1,k2了.不妨设k1>k2,那么给定k1,k2的个数就是phi(k1),因为有序,所以给phi*2,但是,这样是否漏算了呢?没错,漏算了(1,1),补上

欧拉函数

void Euler_Sieve_Method(int * euler, int n) { euler[1] = 1; for (int i = 2; i < n; i++) { euler[i] = i; } for (int i = 2; i < n; i++) { if (euler[i] == i) { for (int j = i; j < n; j += i) { euler[j] = euler[j] / i * (i - 1); } } } } void Euler_Si

hdu1695(莫比乌斯)或欧拉函数+容斥

题意:求1-b和1-d之内各选一个数组成数对,问最大公约数为k的数对有多少个,数对是有序的.(b,d,k<=100000) 解法1: 这个可以简化成1-b/k 和1-d/k 的互质有序数对的个数.假设b=b/k,d=d/k,b<=d.欧拉函数可以算出1-b与1-b之内的互质对数,然后在b+1到d的数i,求每个i在1-b之间有多少互质的数.解法是容斥,getans函数参数的意义:1-tool中含有rem位置之后的i的质因子的数的个数. 在 for(int j=rem;j<=factor[i

欧拉函数常用性质

欧拉函数定义:设n 为正整数,则1,2......,n中与n互质的整数个数记作f(n). 1.1 若n为素数,f(n)=n-1; 1.2 整数n=p*q,p,q为不同素数,则f(n)=f(p)*f(q)=(p-1)*(q-1) 1.3 n=p^a*q^b,f(n)=f(p^a)*f(q^b)=n*(1-1/p)*(1-1/q) 1.4 分解质因子相乘,f(n)=n*(1-1/p1)*(1-1/p2)*.......*(1-1/pk). f(100)=f(2^2*5^2)=100*1/2*4/5=

POJ2478(SummerTrainingDay04-E 欧拉函数)

Farey Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16927   Accepted: 6764 Description The Farey Sequence Fn for any integer n with n >= 2 is the set of irreducible rational numbers a/b with 0 < a < b <= n and gcd(a,b)

POJ 2478 欧拉函数(欧拉筛法) HDU 1576 逆元求法

相关逆元求法,我之前有写过,还有欧拉函数的求法,欧拉函数与逆元的关系  点击 POJ 2478 又是一个打表的题目,一眼看出结果就是前n个欧拉函数值的和. 这里直接计算欧拉函数值求和会超时,看见多组数据. 然后就是计算欧拉函数,打表就好了. #include <stdio.h> #include <string.h> #include <iostream> using namespace std; typedef long long LL; const int N =

算法复习——欧拉函数(poj3090)

题目: Description A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal to 0), other than the origin, is visible from the origin if the line from (0, 0) to (x, y) does not pass through any other lattice point. For exa

欧拉函数之和(51nod 1239)

对正整数n,欧拉函数是小于或等于n的数中与n互质的数的数目.此函数以其首名研究者欧拉命名,它又称为Euler's totient function.φ函数.欧拉商数等.例如:φ(8) = 4(Phi(8) = 4),因为1,3,5,7均和8互质. S(n) = Phi(1) + Phi(2) + ...... Phi(n),给出n,求S(n),例如:n = 5,S(n) = 1 + 1 + 2 + 2 + 4 = 10,定义Phi(1) = 1.由于结果很大,输出Mod 1000000007的结