• 逆元


    求逆元模板

    Part 1:求逆元

    拓展欧几里得求法
    由 a * b=1(mod p) 得 a * b+p * y=1(mod p) 则可以用拓展欧几里得求解

    void ex_gcd( int b, int p, int & a, int & k ) {  //拓展欧几里得
        if( p == 0 ) {
            a = 1; k = 0;
            return;
        }
        ex_gcd( p, b % p, k, a );
        k -= b / p * a;
        return;
    }
    int main() {
        int b, p;
        cin >> b >> p;
        int a, k;
        ex_gcd( b, p, a, k );
        if( a < 0 ) a += p;
        cout << a << endl;
        return 0;
    }
    

    快速幂求法(费马小定理)
    由a^(p-1)=1(mod p)(费马小定理) --> a^(p-2) =a^(-1) (mod p)

    int ksm(int a,int b,int p)
    {
          int ans=1;
          while(b){
                if(b&1) ans=ans*a%p;
                b>>=1;
                a=a*a%p;
          }
          return ans;
    }
    int main() {
        int b, p;
        cin >> b >> p;
        cout<<ksm(b,p-2,p);
        return 0;
    }
    

    Part 2:求出1!,2!,3!,... n!逆元

    先求n!,再利用1/(n-1)!= 1/n!*n%Mod倒推

    int inv( int b, int p ) {
        int a, k;
        exPower( b, p, a, k );
        if( a < 0 ) a += p;
        return a;
    }
    void init( int n ) {
        Fact[ 0 ] = 1;
        for( int i = 1; i <= n; ++i ) Fact[ i ] = Fact[ i - 1 ] * i % Mod;
        INV[ n ] = inv( Fact[ n ], Mod );
        for( int i = n - 1; i >= 0; --i ) INV[ i ] = INV[ i + 1 ] * ( i + 1 ) % Mod;
        return;
    }
    

    Part 3:逆元的线性递推式

    Inv[ 1 ] = 1;
    for( int i = 2; i <= n; i++ )
        Inv[ i ] = ( p - p / i ) * Inv[ p % i ] % p;
    
  • 相关阅读:
    spark动态资源分配
    G1垃圾回收器
    主流八大开源OLAP技术架构对比
    http菜鸟教程
    @Component, @Repository, @Service的区别
    Flink如何保证端到端的一致性
    计算机组成原理
    yarn session和perjob的区别
    hbase为什么不适合scan
    springboot starter
  • 原文地址:https://www.cnblogs.com/Tiork/p/14190401.html
Copyright © 2020-2023  润新知