当前位置:网站首页>数学基础课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 。
边栏推荐
- 0-10V,4-20mA电流电压转PWM隔离转换器 质料以及应用电路图
- HRA隔离系列 宽电压输入 正负高电压稳压输出
- Wireless charging mouse pad RGB LED lighting wireless charging mouse pad
- Composition of wechat applet code
- Rs-485/232 to 4-20ma/0-10v isolated d/a converter
- 配置VsCode中‘log’快捷键去掉console.log(‘‘);中的分号;
- MySQL workbench basically uses [create a database]
- DSL实现Metrics 聚合
- 热电阻pt100 CU50隔离转换器转4-20ma模拟量输出温度变送器0-10V
- Introduction to easydarawin streaming media server
猜你喜欢

2021 - 09 - 15

Go language introduction and application scenario analysis

设置索引库结构,给用户添加可自动补全的suggestion,并将一些字段变成集合放到suggestion里面去

2022-7-15 廉价国产PLC工控板带485主从通信的零散记录

自动补全 & (自定义)拼音分词器 & 搜索时注意事项

HRA2460D-2w高压电源高压模块-高压---高精度hra2460d-2w

DAC7512N 模拟混合信号IC转换器

无线充发光鼠标垫RGB LED照明无线充电鼠标垫

Hra2460d-2w high voltage power supply high voltage module - high voltage - high precision hra2460d-2w

Tips for using tp4054 charging IC -- used in conjunction with Zhongke Lanxun ab5365b
随机推荐
FS5383A锂电池3.7V输入供电太阳能草坪灯驱动IC
c语言调用文件浏览器,实现选择文件的效果
Chrome浏览器设置 【显示右上角 翻译语言图标】
MCU单片机OTP
[simple and fast] after startup, the desktop is normal, and the taskbar below is unresponsive / the mouse keeps turning
嵌入式C语言重点(const、static、voliatile、位运算)
Darwin reflex summary
获取当前年月日、时分秒、星期,并实时更新
数字信号隔离模块 ADUM1401ARWZ 亚德诺 库存现货
串口循环缓存区 简单 免初始化 不用堆、指针、分段memcpy
3.7V lithium battery boost to 5v1a, fs2114 boost conversion chip design layout
MySQL workbench basically uses [create a data table]
Hm9922 switching buck LED constant current driver IC
vscode 配置golang开发环境
国际标准信号0-5V/0-10V/1-5V,0-10mA/0-20mA/4-20mA等的转换隔离和传输
Vscode instant English translation plug-in [translation (English Chinese Dictionary)]
配置VsCode中‘log’快捷键去掉console.log(‘‘);中的分号;
Fs68001 wireless charging SOC chip has simple periphery and schematic diagram of 5W wireless charging scheme
HT7727 HT7730 HT7733 HT7737 HT7750异步DCDC升压IC
minio安装部署及简单使用