蓝桥集训之数论基础

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥集训之数论基础相关的知识,希望对你有一定的参考价值。

一、同余

1.1 结论

  • ( a + b ) m o d      n = ( ( a m o d      n ) + ( b m o d      n ) ) m o d      n (a+b) \\mod \\ n = ((a \\mod \\ n) + (b \\mod \\ n) )\\mod \\ n (a+b)mod n=((amod n)+(bmod n))mod n
  • ( a − b ) m o d      n = ( ( a m o d      n ) − ( b m o d      n ) ) m o d      n (a-b) \\mod \\ n = ((a \\mod \\ n) - (b \\mod \\ n) )\\mod \\ n (ab)mod n=((amod n)(bmod n))mod n
  • ( a × b ) m o d      n = ( ( a m o d      n ) × ( b m o d      n ) ) m o d      n (a \\times b) \\mod \\ n = ((a \\mod \\ n) \\times (b \\mod \\ n) )\\mod \\ n (a×b)mod n=((amod n)×(bmod n))mod n

二、GCD&LCM

2.1 GCD

GCD即最大公约数,小学的时候我们就学习了求两数的最大公约数的方法。但是要注意如果有一个数为0的话那么最小公约数就是另一个不为0的数,我们在这里只需要知道GCD是什么东西就行了

2.1.1 更相减损法

两个正整数a和b(a>b),它们的最大公约数等于a-b的差值c和较小数b的最大公约数。

2.1.2代码:

int gcd_3(int a,int b) //更相减损法 递归写法 
    if(a == 0)
        return b;
    if(b == 0)
        return a; 
    if(a == b)
        return a;
    if(a > b)
        return gcd_3(a-b,b);
    if(a < b)
        return gcd_3(b-a,a);


int gcd_4(int a,int b) //更相减损法 循环写法 
    if(a == 0)
      return b;
    if(b == 0)
      return a;
    while(a != b) 
        if(a > b)
            a -= b;
        else
        
            int t = a;
            a = b - a;
            b = t;
        
    
    return a;

2.1.3 辗转相除法

两个正整数a和b(a>b),它们的最大公约数等于a除以b的余数c和b之间的最大公约数。

其实就是把更相减损变得更高级一点(加减运算变乘除运算,提升了一个级别)

但是大整数取模会让一些题极为头疼,所以我们还是要慎重考虑什么时候用更相减损什么时候用辗转相除。

2.1.4 代码

int gcd_1(int a,int b)//辗转相除法 循环写法 
    while(b > 0) 
        int t = a%b;
        a = b;
        b = t;
    
    return a;

int gcd_2(int a,int b) //辗转相除法 递归写法 
    return b?gcd_2(b,a%b) : a;

2.2 LCM

LCM即最小公倍数,小学的时候也学过,当我们求出GCD的时候,LCM也就出来了,
L C M   =   a × b G C D ( a , b ) LCM\\ = \\ \\fraca \\times bGCD(a, b) LCM = GCD(a,b)a×b

2.3 拓展欧几里得

2.3.1 前置知识

辗转相除法、贝祖定理

  • 辗转相除法就是不断的让较大的数模上较小的数,最后使得其中一个数位0,最后得到答案
  • 贝祖定理:$ax+by=c,x∈Z*,y∈Z* \\ 成 立 的 充 要 条 件 是 成立的充要条件是 gcd(a,b)|c$

贝祖定理证明:

s = g c d ( a , b ) s=gcd(a,b) s=gcd(a,b),显然 s ∣ a s|a sa,并且 s ∣ b s|b sb

又因为 x , y ∈ Z x,y∈Z xyZ

所以 s ∣ a x s|ax sax, s ∣ b y s|by sby

显然要使得之前的式子成立,则必须满足 c c c a a a b b b的公约数的倍数

又因为 x x x y y y是正整数

所以 c c c必然是 a , b a,b a,b最大公约数的倍数。

因此,证得该定理成立

当然我这里写的可能只有两元,但是这个定理可以拓展到n元,请大家思考拓展到n元的情况

2.3.2 问题引出

求得任意一组解: a x + b y = 1 ax+by=1 ax+by=1

2.3.3 思路

很显然,我们能知道如果 g c d ( a , b ) ! = 1 gcd(a,b)!=1 gcd(a,b)!=1的话是无解的,所以我们只看 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1的情况,通过拓展欧几里得的算法我们可以解决这一类问题

2.3.4 拓展欧几里得算法代码

int ex_gcd(int a,int b,int &x,int &y)//返回的值还是GCD(a,b)

    if(b==0)//等于0的情况直接返回了
    
        x=1;
        y=0;
        return a;
    
    int ans=ex_gcd(b,a%b,x,y);//获得x',y';
    int temp=x;//存储x'
    x=y;//x=y'
    y=temp-(a/b)*x;//y=x'-(a/b)*y'
    return ans;

2.3.5 原理证明

a x + b y = c ax+by=c ax+by=c有解,且设 t = g c d ( a , b ) t = gcd(a,b) t=gcd(a,b),则 c % t = 0 c \\% t =0 c%t=0

①设 a x + b y = t ax+by=t ax+by=t

当b等于0时, t = a t=a t=a,因为 g c d ( a , 0 ) = a gcd(a,0)=a gcd(a,0)=a,则会有 a × x = a a\\times x = a a×x=a,即 x = 1 x=1 x=1

② 当b不等于0时

a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b) —Ⅰ

我们可以推出下一层的状态: b x ′ + ( a % b ) y ′ = g c d ( b , a % b ) bx'+(a\\%b)y'=gcd(b,a\\%b) bx+(a%b)y=gcd(b,a%b) — Ⅱ

又因为 g c d ( b , a % b ) = g c d ( a , b ) gcd(b,a\\%b)=gcd(a,b) gcd(b,a%b)=gcd(a,b) — Ⅲ

所以由Ⅰ、Ⅱ、Ⅲ可得: a x + b y = b x ′ + ( a % b ) y ′ ax+by=bx'+(a\\%b)y' ax+by=bx+(a%b)y —Ⅴ

又因为 a % b = a − ⌊ a b ⌋ × b a\\%b = a - \\left \\lfloor \\fracab \\right \\rfloor \\times b a%b=aba×以上是关于蓝桥集训之数论基础的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯之数论专题

蓝桥集训之位运算和相关函数

数论——置换

蓝桥杯省赛题目的难度大概相当于洛谷的啥难度的题?

蓝桥杯集训100题scratch水仙花数 蓝桥杯scratch比赛专项预测编程题 集训模拟练习题第18题

[暑假集训--数论]poj2657 Comfort