数学知识(二)
 20240628
- 求和N互质的个数公式 先分解N,再求个数fai n
- 欧拉函数的证明:用容斥原理 不考
 求质因子 p1, … , pk
 1-N中与N互质的个数, 去掉质因子倍数 是pi的倍数的有N/pi个,但是会有既是p1也是p2…的倍数,那么会重复减,要再加回来(这是高数讲过的)
 个数=N-是一个pi的倍数 + 是两个的pi,pj的倍数- 是三个的pi,pj, pk的倍数+….类推
 奇减偶加
时间复杂度 O(根号n) 主要是分解质因子耗时,所以是根号n
 所以是n*根号ai, 大概4-5百万之间!!!
873 欧拉函数
	#include<iostream>
	#include<algorithm>
	
	using namespace std;
	
	int main(){
	    // 分解质因数
	    int n;
	    cin >> n;
	    while(n --){
	        int a;
	        cin >> a;
	        
	        int res = a; //质因数个数
	        
	        for(int i = 2; i <= a/i; i ++){
	            if(a % i == 0){
	                // res = res *(1- 1 / i); //不能有小数  要先除i
	                res = res / i *(i -1);
	                
	                while(a % i ==0) a /= i;
	            }
	        }
	        
	        // a只有一个最大的质因子他自己
	        if(a > 1) res = res/ a * (a -1);
	        cout << res << endl;
	    }
	    
	    return 0;
	}
874 用筛法求欧拉函数
 20:49
 求每个质因数的欧拉函数
 用On,变快!
一个质数p的欧拉函数(1-p里和p互质的数的个数!)就是p-1
原始
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N =1000010;
int primes[N], cnt;  //cnt 质数的下标??
int phi[N]; //欧拉函数
bool st[N]; //已被晒过了嘛
// 能爆int 用longlong
LL get_eulers(int n){
    // 线性筛法
    for(int i = 2; i <= n; i ++){
        if(!st[i]){
            // i没被筛过,是个质数
            primes[cnt ++] = i;
        }
        
        // 枚举所有质数,把质数的倍数都删了 标记为筛过
      
一个质数p的欧拉函数(1-p里和p互质的数的个数!)就是p-1 
  for(int j = 0; primes[j] <= n/i; j ++){
            st[primes[j] * i ] = true;
            if(i % primes == 0) break;
        }
    }
}
int main(){
    int n;
    cin >> n;
    
    cout << get_eulers(n) << endl;
    
    return 0;
}
优化
 1. 一个质数p的欧拉函数(1-p里和p互质的数的个数!)就是p-1 Phi[i] = I -1
 2. I mod pj =0 则pj是i的质因子,
 那么phi[pj*i] 的欧拉函数 互质个数= ?
因为欧拉函数和pk的次数ak无关,只和pk 有关,出现一个pk,多乘1-1/pk
推出pj是i质因子,那么 phi[i] 已经乘过 1- 1/pj
 那么pj *i的质因子 是1-1/pj不影响,与pj的次数无关!!!!
Phi[pj*i] = pj * phi[i]
 当I mod pj =0
当I mod pj !=0
 pj一定不是i的质因子,而且是pj i 的最小质因子
 多1-1/pj 和pj
 Phi[pji] = pj (1-1/j)* phi[i] = (pj -1) & phi[i]
就是比线性筛模板多了黄色的部分 三种情况
	#include<iostream>
	#include<algorithm>
	
	using namespace std;
	
	typedef long long LL;
	const int N =1000010;
	
	int primes[N], cnt;  //cnt 质数的下标??
	int phi[N]; //欧拉函数
	bool st[N]; //已被晒过了嘛
	
	// 能爆int 用longlong
	LL get_eulers(int n)
	{
	    phi[1] = 1; //特殊
	    
	    // 线性筛法
	    for(int i = 2; i <= n; i ++){
	        if(!st[i]){
	            // 优化了这里
	            phi[i] = i - 1;
	            
	            // i没被筛过,是个质数
	            primes[cnt ++] = i;
	        }
	        
	        // 枚举所有质数,把质数的倍数都删了 标记为筛过
	        for(int j = 0; primes[j] <= n/i; j ++){
	            st[primes[j] * i ] = true;
	            if(i % primes[j] == 0) 
	            {   
	                phi[primes[j] * i] = phi[i] * primes[j];
	                break;
	            }
	            
	            phi[primes[j] *i] = phi[i] * (primes[j] -1);
	        }
	    }
	    
	    LL res = 0;
	    for(int i = 1; i <= n; i++){
	        res += phi[i];
	    }
	    return res;
	}
	
	int main(){
	    int n;
	    cin >> n;
	    
	    cout << get_eulers(n) << endl;
	    
	    return 0;
	}
36;34 欧拉定理 反正不考证明的,不用看
 三 是恒等于
If a与n互质,那么a^phi[n] mod n 恒为1
 推论:欧拉定理等价版本
 当p质数,if a与p互质
 a^phi( p) mod p = 1
 则phi( p) = p-1
证明不用看 跳了
费马小定理,高数下
 设1-n中所有与a互质的数是 两两不相同
 a1, …. , a_phi(n)
 因为a与n互质
 So
 aa1, … , a a_phi(n)两两不相同,而且与n互质
 Why 两两不相同 反证法
 假设存在两个相同的
 aai 三 aaj
 a*(ai -aj) 三 0 mod n
 因为a不为0, 所以ai 恒等于aj矛盾了
所以
 [ a1, …. , a_phi(n) ] mod n
 [aa1, … , a a_phi(n) ] mod n是同一组数,只不过顺序不同
所以 a^phi n mod n三 1
 



















