欧拉函数求法
欧拉函数是指 对正整数n,小于或等于n的数中与n互质的数的数目。
有如下公式:
其中pi为x的质因数(无重复),x不为0
欧拉函数是积性函数——若m,n互质,φ(mn)=φ(m)φ(n)。
特殊性质:当n为奇数时,φ(2n)=φ(n)
欧拉公式的延伸:一个数的所有质因子之和是euler(n)*n/2
欧拉函数还有这样的性质:
设a为N的质因数,若(N % a == 0 && (N / a) % a == 0) 则有E(N)=E(N / a) * a;若(N % a == 0 && (N / a) % a != 0) 则有:E(N) = E(N / a) * (a - 1)。
求法:
直接求某个n的欧拉函数值与筛法预先处理
//直接求解欧拉函数 int euler(int n){ //返回euler(n) int res=n,a=n; for(int i=2;i*i<=a;i++){ if(a%i==0){ res=res/i*(i-1);//先进行除法是为了防止中间数据的溢出 while(a%i==0) a/=i; } } if(a>1) res=res/a*(a-1); return res; } //筛选法打欧拉函数表 /*线性筛O(n)时间复杂度内筛出maxn内欧拉函数值*/ int m[maxn],phi[maxn],p[maxn],pt; //m[i]是i的最小素因数,phi[i]是i的欧拉函数的值,p是素数,pt是素数个数 int make() { phi[1]=1; int N=maxn; int k; for(int i=2;i<N;i++) { if(!m[i])//i是素数 p[pt++]=m[i]=i,phi[i]=i-1; for(int j=0;j<pt&&(k=p[j]*i)<N;j++) { m[k]=p[j]; if(m[i]==p[j])//为了保证以后的数不被再筛,要break { phi[k]=phi[i]*p[j]; /*这里的phi[k]与phi[i]后面的∏(p[i]-1)/p[i]都一样(m[i]==p[j])只差一个p[j],就可以保证∏(p[i]-1)/p[i]前面也一样了*/ break; } else phi[k]=phi[i]*(p[j]-1);//积性函数性质,f(i*k)=f(i)*f(k) } } }