【数论】欧拉函数与欧拉定理

数学杀我

欧拉函数

对于一个正整数 x x x,小于 x x x且和 x x x互质的正整数的个数,记做 φ ( x ) \varphi(x) φ(x)。其中 φ ( 1 ) \varphi(1) φ(1)被定义为 1 1 1
φ ( x ) = x ∏ p ∣ x p − 1 p \varphi(x)=x\prod_{p|x}\frac{p-1}p φ(x)=xpxpp1
部分性质:

  • p p p是质数, φ ( p ) = p − 1 \varphi(p)=p-1 φ(p)=p1
  • x x x是质数 p p p k k k次幂,即 x = p k x=p^k x=pk,有 φ ( x ) = p k − p k − 1 = ( p − 1 ) p k − 1 \varphi(x)=p^k-p^{k-1}=(p-1)p^{k-1} φ(x)=pkpk1=(p1)pk1
  • 欧拉函数是积性函数(若 x , y x,y x,y互质,则 φ ( x y ) = φ ( x ) φ ( y ) \varphi(xy)=\varphi(x)\varphi(y) φ(xy)=φ(x)φ(y))。

根据通式,枚举 x x x的质因数。可枚举 x \sqrt x x 以内的质因数,若存在大于 x \sqrt x x 的质因数则额外处理。
时间复杂度: O ( n ) O(\sqrt n) O(n )

int phi(int x){
  int ans=x;
  for(int i=2;i*i<=x;i++)if(!(x%i)){
    ans-=ans/i;
    while(!(x%i))x/=i;
  }
  if(x>1)ans-=ans/x;
  return ans;
}

欧拉筛

Eratosthenes筛法筛质数:先假设所有的数都是质数。从小到大讨论,若 i i i是质数,则 i i i的倍数全部标记为合数。
用同样的方法求欧拉函数,先设 φ ( i ) = i \varphi(i)=i φ(i)=i,若 i i i是质数,则 i i i的倍数(即包含 i i i这个质因数的数)的函数值都要更新。
时间复杂度: O ( n log ⁡ 2 log ⁡ 2 n ) O(n\log_2\log_2n) O(nlog2log2n)

void make_prime(bool*mk,int n){
  memset(mk,0,sizeof(mk));mk[1]=1;
  for(int i=2;i<=n;i++)if(!mk[i])
    for(int j=i+i;j<=n;j+=i)mk[j]=1;
}
void make_phi(int*phi,int n){
  for(int i=1;i<=n;i++)phi[i]=i;
  for(int i=2;i<=n;i++)if(phi[i]==i)
    for(int j=i;j<=n;j+=i)phi[j]=phi[j]/i*(i-1);
}

Euler筛法筛质数:每个合数仅被它的最小质因数筛去正好一次。
线性筛求欧拉函数利用了欧拉函数的一些性质( p p p为质数):

  • φ ( p ) = p − 1 \varphi(p)=p-1 φ(p)=p1
  • i m o d    p = 0 i\mod p=0 imodp=0,那么 φ ( i p ) = φ ( i ) p \varphi(ip)=\varphi(i)p φ(ip)=φ(i)p
  • i m o d    p ≠ 0 i\mod p\neq0 imodp̸=0,那么 φ ( i p ) = φ ( i ) ( p − 1 ) \varphi(ip)=\varphi(i)(p-1) φ(ip)=φ(i)(p1)

时间复杂度: O ( n ) O(n) O(n)

void make_prime(bool*mk,int*p,int n){
  memset(mk,0,sizeof(mk));mk[1]=1;
  for(int i=2;i<=n;i++){
    if(!mk[i])p[++tot]=i;
    for(int j=1;j<=tot&&i*p[j]<=n;j++){
      mk[i*p[j]]=1;
      if(!(i%p[j]))break;
    }
  }
}
void make_phi(int*phi,bool*mk,int*p,int n){
  memset(mk,0,sizeof(mk));mk[1]=phi[1]=1;
  for(int i=2;i<=n;i++){
    if(!mk[i])p[++tot]=i,phi[i]=i-1;
    for(int j=1;j<=tot&&i*p[j]<=n;j++){
      mk[i*p[j]]=1;
      if(i%p[j])phi[i*p[j]]=phi[i]*(p[j]-1);
      else{phi[i*p[j]]=phi[i]*p[j];break;}
    }
  }
}

GCD的个数(NKOJ 3684)

问题描述
给定两个正整数 n n n, m m m, 求满足下列两个条件的 x x x的个数:
条件1: 1 ⩽ x ⩽ n 1\leqslant x\leqslant n 1xn
条件2: g c d ( x , n ) ⩾ m gcd(x,n)\geqslant m gcd(x,n)m

输入格式
一行,两个整数 n n n m m m

输出格式
一行,一个整数,表示所求结果

样例输入
10 2

样例输出
6

提示
2 ⩽ n ⩽ 1000000000 , 1 ⩽ m ⩽ N 2\leqslant n\leqslant 1000000000,1\leqslant m\leqslant N 2n1000000000,1mN

先考虑满足 x ⩽ n x\leqslant n xn g c d ( x , n ) = d gcd(x,n)=d gcd(x,n)=d x x x的个数,显然 g c d ( x d , n d ) = 1 gcd(\frac xd,\frac nd)=1 gcd(dx,dn)=1
∴ x d \therefore\frac xd dx ⌊ n d ⌋ \lfloor\frac nd\rfloor dn内的与 ⌊ n d ⌋ \lfloor\frac nd\rfloor dn互质的数,总共有 φ ( ⌊ n d ⌋ ) \varphi(\lfloor\frac nd\rfloor) φ(dn)个。
于是只需枚举 n n n的因数 d d d,当 d ⩾ m d\geqslant m dm时答案增加 φ ( ⌊ n d ⌋ ) \varphi(\lfloor\frac nd\rfloor) φ(dn)。由于 n n n较大,可以把枚举量减少到 n \sqrt n n 。特殊情况特殊处理。

#include
typedef long long LL;
LL phi(LL x){
  LL ans=x;
  for(LL i=2;i*i<=x;i++)if(!(x%i)){
    ans=ans-ans/i;
  	while(!(x%i))x=x/i;
  }
  if(x>1)ans=ans-ans/x;
  return ans;
}
int main(){
  LL n,m,ans=0;
  scanf("%lld%lld",&n,&m);
  for(LL d=1;d*d<=n;d++){
    if(d>=m&&!(n%d))ans+=phi(n/d);
    if(d*d<n&&!(n%d)&&n/d>=m)ans+=phi(d);
  }
  printf("%lld\n",ans);
  return 0;
}

费马小定理

如果 p p p是素数,且 a a a p p p互质,即 g c d ( a , p ) = 1 gcd(a,p)=1 gcd(a,p)=1,那么
a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1\pmod p ap11(modp)

证明:
有小于质数 p p p p − 1 p-1 p1个数构成的集合 A = { 1 , 2 , 3 , … , p − 1 } A=\{1,2,3,\ldots,p-1\} A={1,2,3,,p1},显然 A A A中的数都与 p p p互质。
将集合 A A A中的数乘以 a a a并对 p p p取模,放入集合 B B B,于是 B = { a m o d    p , 2 a m o d    p , 3 a m o d    p , … , ( p − 1 ) a m o d    p } B=\{a\mod p,2a\mod p,3a\mod p,\ldots,(p-1)a\mod p\} B={amodp,2amodp,3amodp,,(p1)amodp}
B B B中的数都小于 p p p,并且由于 g c d ( a , p ) = 1 gcd(a,p)=1 gcd(a,p)=1,这些数都与 p p p互质,得到 A = B A=B A=B
将两个集合的元素分别相乘得 ( p − 1 ) ! ≡ ( p − 1 ) ! a p − 1 ( m o d p ) (p-1)!\equiv(p-1)!a^{p-1}\pmod p (p1)!(p1)!ap1(modp)
∴ a p − 1 ≡ 1 ( m o d p ) \therefore a^{p-1}\equiv1\pmod p ap11(modp)

求乘法逆元

因为 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1\pmod p ap11(modp),那么 a ⋅ a p − 2 ≡ 1 ( m o d p ) a\cdot a^{p-2}\equiv1\pmod p aap21(modp)
所以 a p − 2 a^{p-2} ap2就是 a a a关于模 p p p的乘法逆元。

欧拉定理

费马小定理是欧拉定理的一种特殊情况。
a , n a,n a,n为正整数,且 a , n a,n a,n互质,即 g c d ( a , n ) = 1 gcd(a,n)=1 gcd(a,n)=1,则有:
a φ ( n ) ≡ 1 ( m o d n ) a^{\varphi(n)}\equiv1\pmod n aφ(n)1(modn)

证明过程参考费马小定理
a a a n n n互质时,可用欧拉定理降幂。
a b m o d    n = a b m o d    φ ( n ) m o d    n a^b\mod n=a^{b\mod\varphi(n)}\mod n abmodn=abmodφ(n)modn

一般地, b ⩾ φ ( n ) b\geqslant\varphi(n) bφ(n)时:
a b m o d    n = a b m o d    φ ( n ) + φ ( n ) m o d    n a^b\mod n=a^{b\mod\varphi(n)+\varphi(n)}\mod n abmodn=abmodφ(n)+φ(n)modn

你可能感兴趣的:(基础数学)