数论

Ⅰ GCD

(1) 概念

gcd是指最大公约数(Greatest Common Divisor)(18能被2整除,18是2的倍数,2是18的约数)记作(a,b)

几何概念

一个24×60的长方形区域最多可以被分成多个完整的12×12的正方形,所以12是(24,60)的gcd
在这里插入图片描述

(2) 求法

质数分解法

48 = 2 × 2 × 2 × 2 × 3
180 = 2 × 2 × 3 × 3 × 5
在这里插入图片描述

辗转相除法(欧几里得算法)

内容

在这里插入图片描述

求(62,36 )

62 / 36 = 1 (余26) —— (36,26)
36 / 26 = 1 (余 10) —— (26,10)
26 / 10 = 2 (余6) —— (10,6)
10 / 6 = 1 (余4) —— (6,4)
6 / 4 = 1 (余2) —— (4,2)
得到的结果:能放下多少个正方形
余数:剩下的区域能最大能放正方形的尺寸

几何概念

每次取能放下最大正方形的区域
在这里插入图片描述

代码
//递归写法
int gcd(int a,int b)
{
    if(a%b==0)
        return b;
    return gcd(b,a%b);
}

//循环写法
int gcd(int a,int b)
{
    int temp;
    while(b)
    {    
        temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

(3) 性质

  • 满足交换律: g c d ( a , b ) = g c d ( b , a ) gcd(a,b) = gcd(b,a) gcd(a,b)=gcd(b,a)
  • 满足分配律: g c d ( m a , m b ) = m ∗ g c d ( a , b ) gcd(ma,mb) = m *gcd(a,b) gcd(ma,mb)=mgcd(a,b)
  • 在乘法函数中: g c d ( a b , m ) = g c d ( a , m ) ∗ g c d ( b , m ) gcd(ab,m) = gcd(a,m) * gcd(b,m) gcd(ab,m)=gcd(a,m)gcd(b,m)
  • 和最小公倍数(lcm)的关系: g c d ( a , b ) ∗ l c m ( a , b ) = a b gcd(a, b) * lcm(a, b) = ab gcd(a,b)lcm(a,b)=ab
  • 在坐标里,将点(0, 0)和(a, b)连起来,通过整数坐标的点的数目(除了(0, 0)一点之外)就是gcd(a, b)
  • 两个整数的最大公因子和最小公倍数中存在分配律:
  • g c d ( a , l c m ( b , c ) ) = l c m ( g c d ( a , b ) , g c d ( a , c ) ) gcd(a, lcm(b, c)) = lcm(gcd(a, b), gcd(a, c)) gcd(a,lcm(b,c))=lcm(gcd(a,b),gcd(a,c))
  • l c m ( a , g c d ( b , c ) ) = g c d ( l c m ( a , b ) , l c m ( a , c ) ) lcm(a, gcd(b, c)) = gcd(lcm(a, b), lcm(a, c)) lcm(a,gcd(b,c))=gcd(lcm(a,b),lcm(a,c))
  • *扩展欧几里得算法(见后文)
  • m是任意整数,则有 g c d ( a + m ⋅ b , b ) = g c d ( a , b ) gcd(a + m⋅b, b) = gcd(a, b) gcd(a+mb,b)=gcd(a,b)

(4) 相关题目

① 求1-n范围内,不同的数对中,gcd的最大值
② (a,b) + [a,b] = x
③ *Orac and LCM,待改进
④ 蒜头君的数轴,两次gcd

Ⅱ LCM

LCM是指最小公倍数(Least Common Multiple)记作[a,b]

求法

( a , b ) × [ a , b ] = a × b
即:两个数的乘积等于这两个数的最大公约数与最小公倍数的积

应用

分数的加减法
中国剩余定理(正确的题在最小公倍数内有解,有唯一的解)
从集合的角度理解:并集和交集

Ⅲ 算数基本定理

内容

任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积N = P1a1P2a2P3a3…Pnan。这里P1<P2<P3…<Pn均为质数,其中指数ai是正整数。这样的分解称为 N 的标准分解式。
▶ 又叫唯一分解定理
▶ 把对自然数的研究转化为对素数的研究
▶ 存在性 & 唯一性

Ⅳ 分解质因数

就是把一个合数用质因数相乘的形式表示出来,如:30 = 2 × 3 × 5
▶ 可用反证法证明不存在最大的质数

代码

    for (int i = 2; i*i <= n; i++)        
    {
        while (n%i == 0)
        {
            n = n / i;
            cout << i;
            if (n != 1)cout << "*";
        }
    }

Ⅴ 欧拉函数

背景

在这里插入图片描述

内容

在≤x的正整数中,与x互质的数的数目。例如φ(8)=4,因为1,3,5,7均和8互质
在这里插入图片描述
(其中p1, p2……pn为x的所有质因数,x是不为0的整数,φ(1)=1)

性质

① 若n是质数p的k次幂,则有:在这里插入图片描述
----因为除了p的倍数外,其他数都跟n互质。
② 欧拉函数是积性函数:若m,n互质,则有 在这里插入图片描述
例如:
φ ( 72 ) = φ ( 2 3 × 3 2 ) = 2 3 − 1 ( 2 − 1 ) × 3 2 − 1 ( 3 − 1 ) = 2 2 × 1 × 3 × 2 = 24 {\displaystyle \varphi (72)=\varphi (2^{3}\times 3^{2})=2^{3-1}(2-1)\times 3^{2-1}(3-1)=2^{2}\times 1\times 3\times 2=24} φ(72)=φ(23×32)=231(21)×321(31)=22×1×3×2=24

③ 若n为质数,则有在这里插入图片描述
④ 若a为质数,b%a==0,φ(ab)=a*φ(b)

代码

//直接求
int Euler(int  n)
{
    int  ans = n;
    for(int i=2; i*i <= n; ++i)
    {
        if(n%i == 0)
        {
            ans = ans/i*(i-1);
            while(n%i == 0)
                n/=i;
        }
    }
    if(n > 1) ans = ans/n*(n-1);
    return ans;
}

//线性筛法
void getphi(int N){
    phi[1]=1;
    for(int i=2;i<=N;i++){
        if(!mark[i]){  //是素数
            prime[++tot]=i;
            phi[i]=i-1; //性质③
        }
        for(int j=1;j<=tot;j++){
            if(i*prime[j]>N) break;
            mark[i*prime[j]]=1;//标记i*prime[j]不是素数
            if(i%prime[j]==0){//性质④
                phi[i*prime[j]]=phi[i]*prime[j];break;
            }
            else phi[i*prime[j]]=phi[i]*phi[prime[j]];//性质①
        }
    }
}

Ⅵ 同余定理

概念

给定一个正整数m,如果两个整数a和b满足:a-b能够被m整除,即( a - b ) / m得到一个整数,那么就称整数a与b对模m同余,记作a ≡ b ( mod m )。对模m同余是整数的一个等价关系。
例如:9-5能被2整除,所以9 ≡ 5 ( mod 2) ,就是9跟5除以2得到的余数相等

性质

① 对称性:若a ≡ b ( mod m ),则b ≡ a ( mod m )
② 同余式相加:若a ≡ b ( mod m ),c ≡ d ( mod m ),则a ± c ≡ b ± d ( mod m )
③ 同余式相乘:若a ≡ b ( mod m ),c ≡ d ( mod m ),则a * c ≡ b d ( mod m )

Ⅶ 费马小定理

概念

假如 a a a是一个整数, p p p是一个质数,那么 a p − a a^{p}-a apa p p p的倍数,可以表示为 a p ≡ a ( m o d p ) a^{p}\equiv a{\pmod {p}} apa(modp)
如果a不是p的倍数,这个定理也可以写成 a p − 1 ≡ 1 ( m o d p ) a^{{p-1}}\equiv 1{\pmod {p}} ap11(modp)这个书写方式更加常用。

应用

① 计算2100除以13的余数
在这里插入图片描述
余数为3
② 证明:对于任意整数而言,a13-a恒为2730的倍数。
在这里插入图片描述

Ⅷ 欧拉定理——数论定理

(→_→)该定理被认为是数学世界中最美妙的定理之一///欧拉定理实际上是费马小定理的推广//欧拉好腻害!

概念

若n,a为正整数,且n,a互质,则有在这里插入图片描述

比如,令a = 3,n = 5
比5小的正整数中与5互素的数有1、2、3和4,所以φ(5)=4
代入公式可得:a{φ(n)} = 34 = 81
且 81= 80 + 1 Ξ 1 (mod 5)

应用

① 简化幂的模运算
如:计算7222的个位数,即:求7222被10除的余数。
7和10互质,且φ(10)=4
由欧拉定理知:74 Ξ 1(mod 10)
所以7222=(74)55*(72)Ξ155*72Ξ 49 Ξ 9 (mod 10)。

乘法逆元

概念

乘法逆元,是指数学领域群G中任意一个元素a,都在G中有唯一的逆元a‘,具有性质a × a’ = a’ × a = e,其中e为该群的单位元。
在这里插入图片描述

扩展欧几里得算法

概念

▶ 给定2个整数a、b,必存在整数x、y使满足贝祖等式: a x + b y = g c d ( a , b ) ax + by = gcd(a,b) ax+by=gcd(a,b)
▶ 如果a是负数,可以把问题转化成
∣ a ∣ ( − x ) + b y = gcd ⁡ ( ∣ a ∣ , b ) ( ∣ a ∣ \left|a\right|(-x)+by=\gcd(|a|,b)(\left|a\right| a(x)+by=gcd(a,b)a为a的绝对值),然后令 x ′ = ( − x ) x'=(-x) x=(x)

举例

在标准的欧几里得算法中,我们记欲求最大公约数的两个数为 a , b a,b a,b,第 i i i步带余除法得到的商为 q i q_i qi,余数为 r i + 1 {\displaystyle r_{i+1}} ri+1,则欧几里得算法可以写成如下形式:
在这里插入图片描述

当某步得到的 r i + 1 = 0 {\displaystyle r_{i+1}=0} ri+1=0时,计算结束。上一步得到的 r i {\displaystyle r_{i}} ri 即为 a , b a,b a,b的最大公约数。

扩展欧几里得算法在 q i , r i q_i,r_i qiri的基础上增加了两组序列,记作 s i s_{i} si t i t_{i} ti,并令 s 0 = 1 {\displaystyle s_{0}=1} s0=1 s 1 = 0 {\displaystyle s_{1}=0} s1=0 t 0 = 0 t_{0}=0 t0=0 t 1 = 1 {\displaystyle t_{1}=1} t1=1,在欧几里得算法每步计算 r i + 1 = r i − 1 − q i r i {\displaystyle r_{i+1}=r_{i-1}-q_{i}r_{i}} ri+1=ri1qiri之外额外计算 s i + 1 = s i − 1 − q i s i {\displaystyle s_{i+1}=s_{i-1}-q_{i}s_{i}} si+1=si1qisi t i + 1 = t i − 1 − q i t i { t_{i+1}=t_{i-1}-q_{i}t_{i}} ti+1=ti1qiti,即:
在这里插入图片描述
r i + 1 = 0 {\displaystyle r_{i+1}=0} ri+1=0时,得到的s和t就是满足条件的数
下表以 a = 240 , b = 46 {\displaystyle a=240},{\displaystyle b=46} a=240b=46为例演示了扩展欧几里得算法。所得的最大公因数是2,所得贝祖等式为 gcd ⁡ ( 240 , 46 ) = 2 = − 9 ∗ 240 + 47 ∗ 46 {\displaystyle \gcd(240,46)=2=-9*240+47*46} gcd(240,46)=2=9240+4746
在这里插入图片描述
(感觉有点像是通过伴随矩阵求矩阵的逆,你怎么操作我就跟着你一起,后来你达到最简之后,我也就成了答案)

代码

#include <stdio.h>

struct EX_GCD
{
    int s;
    int t;
    int gcd;
};

struct EX_GCD extended_euclidean(int a, int b)
{
    struct EX_GCD ex_gcd;
    if (b == 0)
    {
        ex_gcd.s = 1;
        ex_gcd.t = 0;
        ex_gcd.gcd = 0;
        return ex_gcd;
    }
    int old_r = a, r = b;
    int old_s = 1, s = 0;
    int old_t = 0, t = 1;
    while (r != 0)
    {
        int q = old_r / r;
        int temp = old_r;
        old_r = r;
        r = temp - q * r;
        temp = old_s;
        old_s = s;
        s = temp - q * s;
        temp = old_t;
        old_t = t;
        t = temp - q * t;
    }
    ex_gcd.s = old_s;
    ex_gcd.t = old_t;
    ex_gcd.gcd = old_r;
    return ex_gcd;
}

int main(void)
{
    int a, b;
    printf("Please input two integers divided by a space.\n");
    scanf("%d%d", &a, &b);
    if (a < b)
    {
        int temp = a;
        a = b;
        b = temp;
    }
    struct EX_GCD solution = extended_euclidean(a, b);
    printf("%d*%d+%d*%d=%d\n", solution.s, a, solution.t, b, solution.gcd);
    printf("Press any key to exit.\n");
    getchar();
    getchar();
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值