数学知识(二)
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