1-16数论学习总结

欧几里得算法及扩展

1.
欧几里得辗转相除求最大公约数

//gcd(a, b)
int gcd(int a, int b) {
    return b ? gcd(b, a % b) : a;
}

或者

//gcd(a, b)
int gcd(int a, int b) {
    int t;
    while (b) {
        t = b;
        b = a % b;
        a = t;
    }
    return a;
}

2.
扩展欧几里得求二元方程的一组整数解(还可求通解)
扩展欧几里得 : Ax + By = gcd(A, B);
如果B = 0,则解为 x = 1, y取任意值(一般设为0);

递归扩展

不为0欧几里得思想递归扩展Bs + (A % B)t = gcd(A, B)
B = 0时, 显然 t = 1, s取任意
Bs + (A % B )t = gcd(A,B)=>Bt +(s - (A / B) * t) = gcd(A, B)
所以x = t, y =s - (A / B) * t;
这样就可以用递归思想求出Ax + By = gcd(A, B)的解了

void expgcd(int a, int b, int &x, int &y) {

    if (!b) {
        x = 1;
        y = 0;
        return
    }

    expgcd(b, a % b, y, x);
    y -= a / b * x;
}

解得右边换成其他也是一样的


中国剩余定理

中国剩余定理【孙子定理】详解:

其实就是解方程组:

求res的值
使用中国剩余定理的条件【重要!!!】:
n1,n2,n3……ni 这些数两两互质(互素)!!也就是两两之间的最大公约数是1!!

回到正题:先看一下这个视频,后面的会更好理解!
http://v.youku.com/v_show/id_XMTExNTAzOTIw.html

算法描述:【利用同余的加性和乘性】
令nn = n1×n2×n3×……×ni;
那么也就是说nn是ni的倍数!
所以有:nn/ni是其他n的倍数,不是ni的倍数,而且nn/ni跟ni没有大于1的公约数
【如nn/n2,是n1,n3,n4…的倍数,但不是n2的倍数,而且nn/n2和n2的最大公约数是1,因为上面说了这些数两两互质】
既然nn/ni是其他n的倍数,那么nn/ni这个数模其他n【n1,n2…n[i-1],n[i+1]…】的结果肯定是0,为下面利用同余的加性奠定了基础

所以根据视频那种方法
可以先找到x使得:

假设找到这个x了,那么要满足第i个方程,则利用同余的乘性必有:

那么就是res的一部分,它使得res满足第i个方程
所以利用同余的加性,把满足所有方程的这么一个部分加起来就是求出来的其中一组解了

怎么找x呢?【关键】
∵有重要条件:两两互质
∴nn/ni和ni也互质
∴【根据上述:使用中国剩余定理的条件】
∴由扩展的【欧几里得】得:

∴两边同时模ni得:

跟上面的式子对比,发现x = x0
x0怎么求?
就是利用【扩展欧几里得定理】

Lucas定理

求C(m, n)mod p
解法: 现将m, n 化成p进制数表示
m, n各位求组合数C(mi, ni)连乘 mod p即为解
证法比较容易.

相关题目题解候补.

Mobius反演(待续。。。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值