欧拉函数

欧拉定理:
          对于互质的整数a和n,有aφ(n)  ≡ 1 mod n ( ≡ 同于符号)。证明略过。
费马小定理 a^(p-1)  ≡ 1(mod p,p是质数,所以φ(p) = p - 1); 对于不能被质数p整除的正整数a,有ap ≡ a mod p
 
1)互质:
1.定义
      互质: 又叫互素。若n个整数的最大公因数是1,则称这n个整数互质。(1和任何数都互质)。
2.判断方法
       (1)2个不同的质数一定是互质数。
       (2)一个质数,另一个不为它的倍数,这两个数一定互质。
       (3)1不是质数也不是合数,它和任何一个自然数在一起都是互质数。
       (4)相邻的两个自然数是互质的。如15 和 16
       (5)相邻的两个奇数都是互质的。如49 和 51
       (6)较大数是质数的两个数互质。根据(2)得到
       (7)两个数都是合数(差较大),较小数所有的质因数,都不是较大数的约数,这两个数是互质数。如357 和 715, 357 = 3 * 7 * 17,而3、7和17都不是715的约数,这两个数互质。
       (8)两个数都是合数(差较小),这两个数的差的所有质因数都不是较小数的约数,这两个数是互质数。如85 和 78。85 - 78 = 7, 7不是78的约数,这两个数是互质数。
       (9)两个数都是合数,较大数除以较小数的余数(不为0且大于1)的所有的质因数,都不是较小数的约数,这连个数互素。
2)欧拉函数:
          1.基本内容
                对于正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。如 φ(8) = 4,因为1 3 5 6都与8互质。
          通式: φ(x) = x*(1-1/p1) *(1-1/p2)*(1-1/p3)*(1-1/p4)*...*(1-1/pn);其中p1,p2,...pn为x的所有的质因数,x是不为0的整数。 φ(1) = 1;
               
          (1)p^k的欧拉函数
                    对于给定的一个素数p,φ(p) = p - 1。则对于正整数n = p^k
          (n是质数p 的倍数),φ(n) = p^k - p^(k-1)。
          (2)p * q的欧拉函数
                    假设p,q是2个互质的正整数,则p*q的欧拉函数为φ(p * q) = φ(p)*φ(q);
          gcd(p,q) = 1。
          (3)任意正整数的欧拉函数
                    
Φ(n) = ∏  pik-1(p-1) = n ∏ (1 - 1 / pi)
        i=1                    i=1
对于任意 n > 2,2 | Φ(n) ,因为必存在  p-1 是偶数。
           ∏表示连乘符号。
 
设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)。
 
  2.模板:
         
int ef(int n) 
{ 
    int cnt=n; 
    int i; 
    for(i=2;i<=n;i++) 
        if(n%i==0) 
        { 
            cnt - =cnt/i;      //   (x-x/p1) *(1-1/p2)*(1-1/p3)*(1-1/p4).....
            while(n%i==0) 
                n/=i; 
        } 
        return cnt; 
} 
 
 
求2 ~ n每个数的欧拉函数。
 
#include<map>
#include<set>
#include<string>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<time.h>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 1000000001
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int MAXN = 5000010;
int isnotprime[MAXN],prime[MAXN],cnt;
int er[MAXN];
int L,R;
void Init()
{
    cnt = 0;
    memset(er,0,sizeof(er));
    memset(isnotprime,0,sizeof(isnotprime));
    for(int i = 2; i < MAXN; i++){
        if(!isnotprime[i]){
            er[i] = i - 1;
            prime[cnt++] = i;
        }
        for(int j = 0; j < cnt && 1LL * i * prime[j] < MAXN; j++){
            isnotprime[i * prime[j]] = 1;
            if(i % prime[j] == 0){
                er[i * prime[j]] = er[i] * prime[j];
                break;
            }
            else {
                er[i * prime[j]] = er[i] * (prime[j] - 1);
            }
        }
    }
}
int main()
{
    Init();
    while(~scanf("%d%d",&L,&R)){
        int ans,num;
        ans = L;
        num = er[L];
        for(int i = L + 1; i <= R; i++){
            if(er[i] < num){
                num = er[i];
                ans = i;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
           
 
原文地址:https://www.cnblogs.com/sweat123/p/5452956.html