当前位置:网站首页>数学基础课2_欧拉函数,线性筛,扩欧
数学基础课2_欧拉函数,线性筛,扩欧
2022-07-17 05:13:00 【lovesickman】
欧拉函数
ϕ ( n ) \phi(n) ϕ(n) 表示 1 ∼ n 1 \sim n 1∼n 中与 n n n 互质的数的个数。
N = p 1 α 1 p 2 α 2 p 3 α 3 . . . p k α k N = p_1^{\alpha_1}p_2^{\alpha_2}p_3^{\alpha_3}...p_k^{\alpha_k} N=p1α1p2α2p3α3...pkαk
ϕ ( n ) = N ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) . . . ( 1 − 1 p k ) \phi(n) = N(1-\frac{1}{p_1})(1-\frac{1}{p_2})...(1-\frac{1}{p_k}) ϕ(n)=N(1−p11)(1−p21)...(1−pk1)
利用容斥原理推导。

有一个实现的细节。 N ∗ ( 1 − 1 n ) = N ∗ ( n − 1 n ) = N / n ∗ ( n − 1 ) N*(1-\frac{1}{n}) = N*(\frac{n-1}{n}) = N/n*(n-1) N∗(1−n1)=N∗(nn−1)=N/n∗(n−1)
#include <iostream>
using namespace std;
int phi(int x){
int res = x;
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0){
res = res / i * (i - 1);
while (x % i == 0) x /= i;
}
if (x > 1) res = res / x * (x - 1);
return res;
}
int main(){
int n;
cin >> n;
while (n -- ){
int x;
cin >> x;
cout << phi(x) << endl;
}
return 0;
}
1. 用公式求N个数的欧拉函数 O ( N k ) O(N \sqrt{k}) O(Nk)
#include<iostream>
using namespace std;
const int N=1e6+10;
int p[N],cnt[N];
long long f(int n){
long long res=n;
for(int i=2;i<=n/i;i++){
if(n%i==0){
res=res/i*(i-1);
while(n%i==0){
n/=i;
}
}
}
if(n>1)
res=res/n*(n-1);
return res;
}
int main(){
int n;cin>>n;
while(n--){
int a;cin>>a;
cout<<f(a)<<endl;;
}
return 0;
}
2.线性筛 1 ∼ n 1\sim n 1∼n 中每一个数的欧拉函数 O ( n ) O(n) O(n)
线性筛可以求很多数论函数
当 i i i 是质数的时候, p h i ( i ) = i − 1 phi(i) = i-1 phi(i)=i−1 。
当 i i i 不是质数的时候:
- 当 i % p r e [ j ] = = 0 i \%pre[j] == 0 i%pre[j]==0 , p r e [ j ] 是 i ∗ p r e [ j ] 的 最 小 质 因 子 pre[j] 是 i*pre[j] 的最小质因子 pre[j]是i∗pre[j]的最小质因子,又因为 i i i 中包含质因子 p r e [ j ] pre[j] pre[j] 。
p h i ( n ) phi(n) phi(n) 只和 n n n 分解出的质数有关,和质数的指数无关,所以 p h i [ i ∗ p r e [ j ] ] = p r e [ j ] ∗ p h i [ i ] phi[i*pre[j]] = pre[j] *phi[i] phi[i∗pre[j]]=pre[j]∗phi[i]。
- 当 i % p r e [ j ] ! = 0 i \%pre[j] !=0 i%pre[j]!=0 , p r e [ j ] pre[j] pre[j] 是比 i ∗ p r e [ j ] i*pre[j] i∗pre[j] 的最小质因子还要小的质因子,所以:
p h i ( i ∗ p r e [ j ] ) = p h i ( i ) ∗ p r e [ j ] ∗ ( 1 − 1 p r e [ j ] ) = p h i [ i ] ∗ ( p r e [ j ] − 1 ) phi(i*pre[j]) = phi(i)*pre[j]*(1-\frac{1}{pre[j]}) = phi[i]*(pre[j]-1) phi(i∗pre[j])=phi(i)∗pre[j]∗(1−pre[j]1)=phi[i]∗(pre[j]−1)
int pre[N],cnt,n;
int phi[N];//求1~n中每个数的欧拉函数
bool st[N];
void get_euler(int n){
phi[1]=1;
for(int i=2;i<=n;i++){
if(!st[i]){
pre[cnt++]=i;
phi[i]=i-1;
}
for(int j=0;pre[j]<=n/i;j++){
st[i*pre[j]]=1;
if(i%pre[j]==0){
phi[i*pre[j]] = pre[j] * phi[i];
break;
}
phi[i*pre[j]] = phi[i] * (pre[j]-1);
}
}
}
欧拉函数的应用
欧拉定理:若 a a a 与 n n n 互质,则 a ϕ ( n ) ≡ 1 ( m o d n ) a^{\phi(n)} \equiv 1 (mod \ n) aϕ(n)≡1(mod n)
剩余系?
证明欧拉定理:
前置知识:a和b互质,c和b互质,a * c和b互质
$1\sim n $ 中 有 p h i ( n ) phi(n) phi(n) 个数和 n n n 互质, a 1 , a 2 , . . . , a p h i ( n ) a_1,a_2,...,a_{phi(n)} a1,a2,...,aphi(n)
所以的 a i a_i ai 乘 a a a 有: a 1 ∗ a , a 2 ∗ a , . . . , a p h i ( n ) ∗ a a_1*a,a_2*a,...,a_{phi(n)}*a a1∗a,a2∗a,...,aphi(n)∗a ,这些数也和 n n n 互质。
又因为这些数两两不同,且与 n n n 互质的个数只有 p h i ( n ) phi(n) phi(n) 个,所以上边的两组是在模 n n n 意义下是相等的。
证明为什么第二组数在模 n n n 的意义下两两不同。
反证:假设 a i , a j a_i,a_j ai,aj 在模 n n n 的意义下是相等的有:
a ∗ a i ≡ a ∗ a j ( m o d n ) a*a_i \equiv a*a_j (mod \ n) a∗ai≡a∗aj(mod n)
a ∗ ( a i − a j ) ≡ 0 ( m o d n ) a*(a_i-a_j) \equiv 0 (mod \ n) a∗(ai−aj)≡0(mod n)
又因为 a a a 和 n n n 是互质的(大条件),所以有 a i − a j ≡ 0 ( m o d n ) a_i-a_j \equiv 0 (mod \ n) ai−aj≡0(mod n) 与1式子矛盾,得证。
#####欧拉定理的特例:费马定理:当 n n n 是质数,且 a a a 与 n n n 互质的时候 a n − 1 ≡ 1 ( m o d n ) a^{n-1} \equiv 1 (mod \ n) an−1≡1(mod n)
两组数的乘积在模 n n n 的意义下是相等的。乘起来化简就证明了欧拉定理。
欧拉定理的推论
若正整数 a a a , n n n 互质,则对于任意正整数 b b b , 有 a b ≡ a b m o d ϕ ( n ) m o d ( n ) a^b \equiv a^{b \ mod \ \phi(n) }\ mod \ (n) ab≡ab mod ϕ(n) mod (n)
蓝书上给出了精简的证明:
b = q ∗ ( ϕ ( n ) ) + r b = q*(\phi(n))+r b=q∗(ϕ(n))+r , 0 ≤ r < ϕ ( n ) 0 \leq r < \phi(n) 0≤r<ϕ(n) ,有:
a b ≡ a q ∗ ( ϕ ( n ) ) + r ≡ a ϕ ( n ) q ∗ a r ≡ 1 q ∗ a r ≡ a r ≡ a b m o d ϕ ( n ) m o d ( n ) a^b \equiv a^{q*(\phi(n))+r} \equiv a^{\phi(n)^{q}}*a^r \equiv 1^q*a^r\equiv a^{r} \equiv a^{b \ mod\ \phi(n)}\ mod \ (n) ab≡aq∗(ϕ(n))+r≡aϕ(n)q∗ar≡1q∗ar≡ar≡ab mod ϕ(n) mod (n)
特别的,如果 a a a 和 n n n 不互质,当 b > ϕ ( n ) b> \phi(n) b>ϕ(n) 时,有 a b ≡ a b m o d ϕ ( n ) + ϕ ( n ) m o d ( n ) a^b \equiv a^{b \ mod\ \phi(n) + \phi(n)} \ mod \ (n) ab≡ab mod ϕ(n)+ϕ(n) mod (n)
逆元
若 b b b, m m m 互质, b ∣ a b|a b∣a, a b ≡ a ∗ x ( m o d n ) \frac{a}{b} \equiv a*x (mod \ n) ba≡a∗x(mod n)
a b ≡ a ∗ b − 1 ( m o d n ) \frac{a}{b} \equiv a*b^{-1} (mod \ n) ba≡a∗b−1(mod n)
x x x 叫做 b b b 模 n n n 的乘法逆元。记作 b − 1 b^{-1} b−1(是个整数)
证明:
发现了盲点! 费马小定理有两种表述方式:
当 n n n 是质数,且 a a a 与 n n n 互质的时候 a n − 1 ≡ 1 ( m o d n ) a^{n-1} \equiv 1 \ (mod \ n) an−1≡1 (mod n)
当 n n n 是质数,则对于任意整数 a a a , 有 a n ≡ a ( m o d n ) a^{n} \equiv a \ (mod \ n) an≡a (mod n)
原理很简单,当 a a a 与 n n n 互质的时候, a % n ! = 0 a\%n!=0 a%n!=0 , 同于式两边就是消去 a a a 了。
利用 费马定理 :
a ∗ x ≡ 1 ( m o d p ) a ∗ x ≡ a p − 1 ( m o d p ) x ≡ a p − 2 ( m o d p ) a*x \equiv 1 (mod\ p)\\ a*x \equiv a^{p-1} (mod \ p)\\ x \equiv a^{p-2} (mod \ p) a∗x≡1(mod p)a∗x≡ap−1(mod p)x≡ap−2(mod p)
无解的情况:如果 a a a 是 p p p 的倍数,那么 p ∣ a ∗ x p|a*x p∣a∗x 有, a ∗ x m o d p = 0 a*x \ mod\ p =0 a∗x mod p=0,原式不成立。
裴蜀定理
对于任意正整数 a , b a,b a,b ,一定存在整数 x , y x,y x,y ,使得: a x + b y = g c d ( a , b ) ax+by = gcd(a,b) ax+by=gcd(a,b)
可以发现 ( a , b ) (a,b) (a,b) 和 a 和 b a和b a和b 能凑出来的最小的正整数。
(a-1)*(b-1)-1 是 a和b 不能凑出来的最大的正整数。
裴蜀定理的证明是通过扩展欧几里得算法得到的。
扩展欧几里得算法
#include<iostream>
#include<algorithm>
using namespace std;
int extgcd(int a,int b,int &x,int &y)// 返回的是gcd(a,b)
{
if(b==0){
// a*x+b*y=gcd(a,b)
// a + 0 = gcd(a,0) = a
x=1,y=0;
return a;
}
/* 递归求解的, b*y+(a%b)*x=gcd(b,a%b)=gcd(a,b) 化简得到 x * a +[y-a/b*x] b = gcd(a,b) a的系数还是x; y-=(a/b*x); */
int d=extgcd(b,a%b,y,x);//记得翻转 x,y
y-=a/b*x;
return d;
}
int main()
{
int n;cin>>n;
while(n--)
{
int a,b,x,y;
scanf("%d%d",&a,&b);
int t=extgcd(a,b,x,y);
printf("%d %d\n",x,y);
}
return 0;
}
扩展欧几里得的通解。
a x 0 + b y 0 = d x = x 0 − b d k , k ∈ z y = y 0 + a d k ax_0+by_0=d\\ x = x_0-\frac{b}{d}k,k\in z\\ y = y_0+\frac{a}{d}k ax0+by0=dx=x0−dbk,k∈zy=y0+dak
扩欧应用,求解线性同余方程
a x ≡ b ( m o d m ) ax \equiv b \ (mod \ m) ax≡b (mod m)
a x − m y = b ax-my=b ax−my=b , 方程有解的充要条件 g c d ( a , m ) ∣ b gcd(a,m)|b gcd(a,m)∣b
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
int exgcd(int a, int b, int &x, int &y)
{
if (!b){
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main()
{
int n;
scanf("%d", &n);
while (n -- )
{
int a, b, m;
scanf("%d%d%d", &a, &b, &m);
int x, y;
int d = exgcd(a, m, x, y);
if (b % d) puts("impossible");
else printf("%d\n", (LL)b / d * x % m);
}
return 0;
}
在用扩展欧几里得算法求逆元的基础上的 中国剩余定理
设 m 1 , m 2 , . . . , m n m_1,m_2,...,m_n m1,m2,...,mn 是两两互质 的整数, M = ∏ i = 1 n m i M = \prod_{i=1}^{n} m_i M=∏i=1nmi , M i = M m i M_i = \frac{M}{m_i} Mi=miM 。
对于 n n n 个整数 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an 方程组。
x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) . . . x ≡ a n ( m o d m n ) x \equiv a_1 (mod \ m_1)\\ x \equiv a_2 (mod \ m_2)\\ ...\\ x \equiv a_n (mod \ m_n) x≡a1(mod m1)x≡a2(mod m2)...x≡an(mod mn)
构造出一组解: x = a 1 ∗ M 1 ∗ M 1 − 1 + a 2 ∗ M 2 ∗ M 2 − 1 + . . . + a n ∗ M n ∗ M n − 1 x = a_1 * M_1*M_1^{-1}+a_2 * M_2*M_2^{-1}+...+a_n * M_n*M_n^{-1} x=a1∗M1∗M1−1+a2∗M2∗M2−1+...+an∗Mn∗Mn−1 。
边栏推荐
猜你喜欢
自动补全 & (自定义)拼音分词器 & 搜索时注意事项
IT4058A型号单节锂离子电池充电管理
MySQL Workbench基本使用【创建一个数据库】
Fs68001 wireless charging SOC chip has simple periphery and schematic diagram of 5W wireless charging scheme
Go language introduction and application scenario analysis
数字信号隔离模块 ADUM1401ARWZ 亚德诺 库存现货
索引库中的文档的操作
mapping索引属性 & 创建索的操作
3.7V锂电池升压到5V1A,FS2114升压转换芯片设计布局
Hm8203 linear two string charging management controller IC
随机推荐
[详细教程安装][配置] VsCode中关于Eslint的辅助插件
vscode 使用技巧1
Low power LDO linear regulator IC
自动补全 & (自定义)拼音分词器 & 搜索时注意事项
Rs-485/232 to 4-20ma/0-10v isolated d/a converter
MCU单片机OTP
Lithium battery charging management chip
Fs68001 wireless charging SOC chip has simple periphery and schematic diagram of 5W wireless charging scheme
嵌入式C语言重点(const、static、voliatile、位运算)
2021-11-17 ESP32引脚参考
升压DC/DC转换器
4-20mA to 4-20mA 0-5V to 0-5V analog signal isolation transmitter
压力应变桥信号处理光电隔离放大器
隔离4-20mA或0-20mA信号传输
Darwin Streaming Server 介绍
Vscode instant English translation plug-in [translation (English Chinese Dictionary)]
c语言 指定日期开始多少天 显示
Complete scheme diagram of lth7 five pin chip fs4054 charging circuit principle
2021-11-10 micropyton tb6600 step drive class
解决Cannot read properties of null (reading ‘pickAlgorithm‘)