zoukankan      html  css  js  c++  java
  • 基础数学

    扩展欧几里得

    在讲欧几里得之前我想写说gcd,因为在我学习exgcd时候没有深刻理解递归gcd导致看了很长时间的exgcd的都代码才懂

    辗转相除

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

    ​ 在辗转相除的应用中我们可以知道的是gcd(a,b)=gcd(b,a%b);然后层层递归求得当b=0时候的解

    贝祖定理

    当a,b∈Z,那么一定存在x,y∈Z使得ax+by=gcd(a,b);

    现在给出一个方程ax+by=m,如果此方程有解,那么m一定是gcd的若干倍(用来判断这样的式子是否有解)

    特例:

    ​ ax+by=1,此时gcd=1

    扩展欧几里得

    板子:

    int exgcd(int a,int b,int &x,int &y)
    {
        if(b==0){
            x=1,y=0;
            return a;
        }
        int r=exgcd(b,a%b,y,x);
        y-=a/b*x;
        return r;
    }
    

    要注意的是这个板子是简化版直接替换了x,y的位置

    完整版:

    int exgcd(int a,int b,int &x,int &y)
    {
        if(b==0){
            x=1,y=0;
            return a;
        }
        int r=exgcd(b,a%b,x,y);
        int tmp=x;
        x=y;
        y=tmp-a/b*y;
        return r;
    }
    

    逆元

    为什么要求逆元?

    因为除法求余是错误的!- (a÷b)%c=(a%c÷b%c)%*c*

    exgcd求逆元

    int exgcd(int a,int b,int &x,int &y)
    {
        if(b==0){
            x=1,y=0;
            return a;
        }
        int r=exgcd(b,a%b,y,x);
        y-=a/b*x;
        return r;
    }
    

    要注意的是求出来的逆元可能是‘负值’,还有后面的处理

    	ll x=0,y=0;exgcd(b,mod,x,y);
    	if(x<0) x+=mod;
    	ll ans=(n*((x%mod+mod)%mod))%mod;
    

    这里的x就是a%b的逆元,y是b%a的逆元

    注意

    ​ 要理解引用的用法

    费马小定理

    快速幂求逆元-求a的p-2次方

    前提:

    ​ gcd(a,p)=1且p为质数--具体不清楚以后再来补这个坑

    递推求阶乘逆元-未理解直接抄的

    我们经常会用到阶乘的逆元,我们可以考虑用费马小定理先求出最大那个阶乘的逆元,然后再往回推,直接看代码再解释。

    void init() {
    	fact[0] = 1;
    	for (int i = 1; i < maxn; i++) {
    		fact[i] = fact[i - 1] * i %mod;
    	}
    	inv[maxn - 1] = power(fact[maxn - 1], mod - 2);
    	for (int i = maxn - 2; i >= 0; i--) {
    		inv[i] = inv[i + 1] * (i + 1) %mod;
    	}
    }
    
    

  • 相关阅读:
    with异常
    内建函数的重写
    布尔测试函数重写
    函数重写
    类中的对象属性管理函数
    类中的迭代器__iter__
    多继承
    多态
    封装
    深入理解Java:类加载机制及反射
  • 原文地址:https://www.cnblogs.com/waryan/p/12668640.html
Copyright © 2011-2022 走看看