√n求单值欧拉函数

基本定理:

首先看一下核心代码:

核心代码

原理解析:

当初我看不懂这段代码,主要有这么几个问题:

1.定理里面不是一开始写了一个n*xxx么?为什么代码里没有*n?

2.ans不是*(prime[i]-1)么?为什么到了第二个while循环变成*prime[i]了?

3.定理里面不是要/pi么?为什么代码里没有/pi?????????????

公式化简

首先我们来分析一下整个程序的原理,如果把程序的原理搞明白了,这三个问题也就自然而然的解决了

这个程序的原理是基于唯一分解定理:

那么我们可以把n拆开,再带回到欧拉函数公式中,然后再约分一下:

LaTex代码:

1 ans=p_1^a^1*p_2^a^2*.......*p_i^a^i*\frac{p_1-1}{p_1}*\frac{p_2-1}{p_2}*....*\frac{p_i-1}{p_i}
2    \newline
3    =p_1^a^1*\frac{p_1-1}{p_1}*.......*p_2^a^2*\frac{p_2-1}{p_2}*....p_i^a^i*\frac{p_i-1}{p_i}
4    \newline
5    =p_1^a^{1-1}*({p_1-1})*.......*p_2^a^{2-1}*({p_2-1})*....p_i^a^{i-1}*({p_i-1})

解答问题

首先这里的代码实现还有一个小技巧:
我们在while之前把x/prime[i],这就相当于让ans少*一个prime[i],这样就可以解决求指数ai-1的问题了

现在再回去看一下刚开始的三个问题,仔细想一想

提示:

下面有答案,

但请认真思考以后再看,

答案在下面:

1.定理里面不是一开始写了一个n*xxx么?为什么代码里没有*n?

因为n被唯一分解了,while循环里面的内容就是用来*n的

2.ans不是*(prime[i]-1)么?为什么到了第二个while循环变成*prime[i]了?

*prime是为了让答案最终*n

3.定理里面不是要/pi么?为什么代码里没有/pi?????????????

被化简了,不明白的可以看上面的化简过程

完整代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 const int MAXN=1000001;
 7 int prime[MAXN];
 8 int mu[MAXN]= {0,1};
 9 int n;
10 int tot=0;
11 int vis[MAXN]= {1,1};
12 void read(int &n) {
13     char c=‘+‘;
14     int x=0;
15     bool flag=0;
16     while(c<‘0‘||c>‘9‘) {
17         c=getchar();
18         if(c==‘-‘)flag=1;
19     }
20     while(c>=‘0‘&&c<=‘9‘) {
21         x=x*10+c-48;
22         c=getchar();
23     }
24     flag==1?n=-x:n=x;
25 }
26 void ou() {
27     for(int i=2; i<=n; i++) {
28         if(!vis[i])
29             prime[++tot]=i,mu[i]=-1;
30         for(int j=1; j<=tot&&j*prime[i]<=n; j++) {
31             vis[i*prime[j]]=1;
32             if((i%prime[j])==0) {
33                 mu[i*prime[j]]=0;
34                 break;
35             }
36             mu[i*prime[j]]=-mu[i];
37         }
38     }
39 }
40 int getphi(int x) {
41     int ans=1;
42     for(int i=1; i<=tot&&prime[i]*prime[i]<=x; i++)
43     {
44         if(x%prime[i]==0)
45         {
46             ans*=(prime[i]-1);
47             x=x/prime[i];
48             while(x%prime[i]==0)
49             {
50             ans*=prime[i];
51             x/=prime[i];
52             }
53         }
54
55     }
56     if(x>1)
57         ans*=x-1;
58     return ans;
59 }
60 int main() {
61     n=1001;
62     ou();
63     int c;
64     printf("please input the num\n");
65     while(cin>>c)
66         printf("the num`s phi is %d\n",getphi(c));
67     return 0;
68
69 }

里面还乱入了线性求莫比乌斯函数的方法,,

懒得删了,,,

结尾啰嗦几句

求单值欧拉函数就讲到这里,

其实对于这份代码还有一种很玄学的理解方法,

但是我的这种方法比较简单易懂,

而且这两种理解方法从本质上来说是一样的

这里不在赘述

最后再说一下,这里只介绍了求单值欧拉函数的方法,

实际上欧拉函数还有线性筛法(因为欧拉函数是积性函数)

有空再介绍吧

另外,因为本人是第一次接触欧拉函数,所以本文肯定有成堆的bug,如果您找出了bug,可以在评论区留言或者通过其他方式联系本人,

谢谢!

时间: 2024-07-30 13:31:49

√n求单值欧拉函数的相关文章

O(n)求素数,求欧拉函数,求莫比乌斯函数,求对mod的逆元,各种求

筛素数 void shai() { no[1]=true;no[0]=true; for(int i=2;i<=r;i++) { if(!no[i]) p[++p[0]]=i; int j=1,t=i*p[1]; while(j<=p[0] && t<=r) { no[t]=true; if(i%p[j]==0) //每一个数字都有最小质因子.这里往后的数都会被筛过的,break break; t=i*p[++j]; } } } O(n)筛欧拉函数 void find()

欧拉函数o(n)求素数

欧拉函数的定义: E(N)= ( 区间[1,N-1] 中与 N 互质的整数个数). 对于 积性函数 F(X*Y),当且仅当 GCD(X,Y)= 1 时, F(X*Y) = F(X)* F(Y) 任意整数可因式分解为如下形式: 其中( p1, p2 - pk 为质数, ei 为次数 ) 所以 因为 欧拉函数 E(X)为积性函数, 所以 对于 , 我们知道 因为pi 为质数,所以 [ 1, pi-1 ] 区间的数都与 pi 互质 对于 区间[ 1, ] ,共有 个数, 因为 只有一个质因子, 所以与

(hdu step 7.2.1)The Euler function(欧拉函数模板题——求phi[a]到phi[b]的和)

题目: The Euler function Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 166 Accepted Submission(s): 96   Problem Description The Euler function phi is an important kind of function in number theory

【转】欧拉函数

链接:http://www.cnblogs.com/yefeng1627/archive/2013/01/02/2842492.html 欧拉函数直接计算公式 欧拉函数的定义: E(N)= (  区间[1,N-1] 中与 N 互质的整数个数). 对于 积性函数 F(X*Y),当且仅当 GCD(X,Y)= 1 时, F(X*Y) = F(X)* F(Y) 任意整数可因式分解为如下形式:      其中( p1, p2 ... pk 为质数, ei 为次数 ) 所以 因为 欧拉函数 E(X)为积性函

数论五&#183;欧拉函数

#1298 : 数论五·欧拉函数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho有时候会用密码写信来互相联系,他们用了一个很大的数当做密钥.小Hi和小Ho约定了一个区间[L,R],每次小Hi和小Ho会选择其中的一个数作为密钥. 小Hi:小Ho,这次我们选[L,R]中的一个数K. 小Ho:恩,小Hi,这个K是多少啊? 小Hi:这个K嘛,不如这一次小Ho你自己想办法算一算怎么样?我这次选择的K满足这样一个条件: 假设φ(n)表示1..n-1中与n互质的数

POJ 2480 (约数+欧拉函数)

题目链接: http://poj.org/problem?id=2480 题目大意:求Σgcd(i,n). 解题思路: 如果i与n互质,gcd(i,n)=1,且总和=欧拉函数phi(n). 如果i与n不互质,那么只要枚举n的全部约数,对于一个约数d,必有gcd(i/d,n/d)互质,这部分的gcd和=d*欧拉函数phi(n/d). 不断累加暴力求解即可. 其实还可以公式化简,不过实在太繁琐了.可以参考金海峰神的解释. 由于要求好多欧拉函数,每次都分解质因数法必然TLE,这里所以采用O(√n)求单

The Euler function(欧拉函数筛)

这题用欧拉函数会超时,要用函数筛. 解析:(转) 定义:对于正整数n,φ(n)是小于或等于n的正整数中,与n互质的数的数目. 例如:φ(8)=4,因为1,3,5,7均和8互质. 性质:1.若p是质数,φ(p)= p-1. 2.若n是质数p的k次幂,φ(n)=(p-1)*p^(k-1).因为除了p的倍数都与n互质 3.欧拉函数是积性函数,若m,n互质,φ(mn)= φ(m)φ(n). 根据这3条性质我们就可以推出一个整数的欧拉函数的公式.因为一个数总可以写成一些质数的乘积的形式. E(k)=(p1

欧拉函数详解

欧拉函数 我们用$\phi(n)$表示欧拉函数 定义:$\phi(n)$表示对于整数$n$,小于等于$n$中与$n$互质的数的个数 性质 1.$\phi(n)$为积性函数 2.$\sum_{d|n}\phi(d)=n$ 3.$1$到$n$中与$n$互质的数的和为$n*\dfrac{\phi(n)}{2}(n>1)$ 计算方法 $\sqrt(n)$计算单值欧拉函数 假设我们需要计算$\phi(n)$ 分情况讨论 1.当$n=1$时 很明显,答案为$1$ 2.当$n$为质数时 根据素数的定义,答案为

线性(欧拉)筛&amp;欧拉函数

线性筛法 what is 线性筛??就是基于最基本的筛法的优化. 在基础的筛法上,我们发现有的数字会被重复筛,例如6既会被2枚举到也会被3枚举到,必然有重复运算. 我们的做法就是让每一个数的最小因数筛. \(FOR\) \(EXAMPLE:\) 有一个数\(2 * 2 * 3 * 5\) 有另一个数 \(3 * 3 * 3* 5\) 那么第一个数枚举到3的话,筛到的数字是\(2 * 2 * 3 * 3 * 5\) 但是在第二个数字再次枚举的时候 枚举到2时 也会枚举到\(2 * 2 * 3 *