欧拉函数
ϕ(n)\phi(n)ϕ(n) 表示 1∼n1 \sim n1∼n 中与 nnn 互质的数的个数。
N=p1α1p2α2p3α3...pkαkN = 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−1p1)(1−1p2)...(1−1pk)\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−1n)=N∗(n−1n)=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(Nk)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∼n1\sim n1∼n 中每一个数的欧拉函数 O(n)O(n)O(n)
线性筛可以求很多数论函数
当 iii 是质数的时候,phi(i)=i−1phi(i) = i-1phi(i)=i−1 。
当 iii 不是质数的时候:
- 当 i%pre[j]==0i \%pre[j] == 0i%pre[j]==0 , pre[j]是i∗pre[j]的最小质因子pre[j] 是 i*pre[j] 的最小质因子pre[j]是i∗pre[j]的最小质因子,又因为 iii 中包含质因子 pre[j]pre[j]pre[j] 。
phi(n)phi(n)phi(n) 只和 nnn 分解出的质数有关,和质数的指数无关,所以 phi[i∗pre[j]]=pre[j]∗phi[i]phi[i*pre[j]] = pre[j] *phi[i]phi[i∗pre[j]]=pre[j]∗phi[i]。
- 当 i%pre[j]!=0i \%pre[j] !=0i%pre[j]!=0 ,pre[j]pre[j]pre[j] 是比 i∗pre[j]i*pre[j]i∗pre[j] 的最小质因子还要小的质因子,所以:
phi(i∗pre[j])=phi(i)∗pre[j]∗(1−1pre[j])=phi[i]∗(pre[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);
}
}
}
欧拉函数的应用
欧拉定理:若 aaa 与 nnn 互质,则 aϕ(n)≡1(mod n)a^{\phi(n)} \equiv 1 (mod \ n)aϕ(n)≡1(mod n)
剩余系?
证明欧拉定理:
前置知识:a和b互质,c和b互质,a * c和b互质
$1\sim n $ 中 有 phi(n)phi(n)phi(n) 个数和 nnn 互质,a1,a2,...,aphi(n)a_1,a_2,...,a_{phi(n)}a1,a2,...,aphi(n)
所以的 aia_iai 乘 aaa 有:a1∗a,a2∗a,...,aphi(n)∗aa_1*a,a_2*a,...,a_{phi(n)}*aa1∗a,a2∗a,...,aphi(n)∗a ,这些数也和 nnn 互质。
又因为这些数两两不同,且与 nnn 互质的个数只有 phi(n)phi(n)phi(n) 个,所以上边的两组是在模 nnn 意义下是相等的。
证明为什么第二组数在模 nnn 的意义下两两不同。
反证:假设 ai,aja_i,a_jai,aj 在模 nnn 的意义下是相等的有:
a∗ai≡a∗aj(mod n)a*a_i \equiv a*a_j (mod \ n)a∗ai≡a∗aj(mod n)
a∗(ai−aj)≡0(mod n)a*(a_i-a_j) \equiv 0 (mod \ n)a∗(ai−aj)≡0(mod n)
又因为 aaa 和 nnn 是互质的(大条件),所以有 ai−aj≡0(mod n)a_i-a_j \equiv 0 (mod \ n)ai−aj≡0(mod n) 与1式子矛盾,得证。
#####欧拉定理的特例:费马定理:当 nnn 是质数,且 aaa 与 nnn 互质的时候 an−1≡1(mod n)a^{n-1} \equiv 1 (mod \ n)an−1≡1(mod n)
两组数的乘积在模 nnn 的意义下是相等的。乘起来化简就证明了欧拉定理。
欧拉定理的推论
若正整数 aaa , nnn 互质,则对于任意正整数 bbb , 有 ab≡ab mod ϕ(n) mod (n)a^b \equiv a^{b \ mod \ \phi(n) }\ mod \ (n)ab≡ab mod ϕ(n) mod (n)
蓝书上给出了精简的证明:
b=q∗(ϕ(n))+rb = q*(\phi(n))+rb=q∗(ϕ(n))+r , 0≤r<ϕ(n)0 \leq r < \phi(n)0≤r<ϕ(n) ,有:
ab≡aq∗(ϕ(n))+r≡aϕ(n)q∗ar≡1q∗ar≡ar≡ab mod ϕ(n) mod (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)
特别的,如果 aaa 和 nnn 不互质,当 b>ϕ(n)b> \phi(n)b>ϕ(n) 时,有 ab≡ab mod ϕ(n)+ϕ(n) mod (n)a^b \equiv a^{b \ mod\ \phi(n) + \phi(n)} \ mod \ (n)ab≡ab mod ϕ(n)+ϕ(n) mod (n)
逆元
若 bbb, mmm 互质,b∣ab|ab∣a,ab≡a∗x(mod n)\frac{a}{b} \equiv a*x (mod \ n)ba≡a∗x(mod n)
ab≡a∗b−1(mod n)\frac{a}{b} \equiv a*b^{-1} (mod \ n)ba≡a∗b−1(mod n)
xxx 叫做 bbb 模 nnn 的乘法逆元。记作 b−1b^{-1}b−1(是个整数)
证明:
发现了盲点! 费马小定理有两种表述方式:
当 nnn 是质数,且 aaa 与 nnn 互质的时候 an−1≡1 (mod n)a^{n-1} \equiv 1 \ (mod \ n)an−1≡1 (mod n)
当 nnn 是质数,则对于任意整数 aaa , 有 an≡a (mod n)a^{n} \equiv a \ (mod \ n)an≡a (mod n)
原理很简单,当 aaa 与 nnn 互质的时候, a%n!=0a\%n!=0a%n!=0 , 同于式两边就是消去 aaa 了。
利用 费马定理 :
a∗x≡1(mod p)a∗x≡ap−1(mod p)x≡ap−2(mod 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)
无解的情况:如果 aaa 是 ppp 的倍数,那么 p∣a∗xp|a*xp∣a∗x 有,a∗x mod p=0a*x \ mod\ p =0a∗x mod p=0,原式不成立。
裴蜀定理
对于任意正整数 a,ba,ba,b ,一定存在整数 x,yx,yx,y ,使得: ax+by=gcd(a,b)ax+by = gcd(a,b)ax+by=gcd(a,b)
可以发现 (a,b)(a,b)(a,b) 和 a和ba和ba和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;
}
扩展欧几里得的通解。
ax0+by0=dx=x0−bdk,k∈zy=y0+adkax_0+by_0=d\\ x = x_0-\frac{b}{d}k,k\in z\\ y = y_0+\frac{a}{d}kax0+by0=dx=x0−dbk,k∈zy=y0+dak
扩欧应用,求解线性同余方程
ax≡b (mod m)ax \equiv b \ (mod \ m)ax≡b (mod m)
ax−my=bax-my=bax−my=b , 方程有解的充要条件 gcd(a,m)∣bgcd(a,m)|bgcd(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;
}
在用扩展欧几里得算法求逆元的基础上的 中国剩余定理
设 m1,m2,...,mnm_1,m_2,...,m_nm1,m2,...,mn 是两两互质 的整数,M=∏i=1nmiM = \prod_{i=1}^{n} m_iM=∏i=1nmi ,Mi=MmiM_i = \frac{M}{m_i}Mi=miM 。
对于 nnn 个整数 a1,a2,...,ana_1,a_2,...,a_na1,a2,...,an 方程组。
x≡a1(mod m1)x≡a2(mod m2)...x≡an(mod mn)
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=a1∗M1∗M1−1+a2∗M2∗M2−1+...+an∗Mn∗Mn−1x = 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 。
本文详细介绍了欧拉函数的定义、性质及计算方法,包括线性筛法和容斥原理推导。此外,还探讨了欧拉定理及其在剩余系、逆元和中国剩余定理中的应用。内容涵盖了费马小定理、裴蜀定理以及扩展欧几里得算法。
765

被折叠的 条评论
为什么被折叠?



