zoukankan      html  css  js  c++  java
  • 信息学中的一些些数论

    因为本人数论较差,于是在noip前复习发现较大漏洞,特此作此篇记录一下。

    一、逆元相关

    首先我们先引入%运算

    (a +  b) % p =  (a%p +  b%p) %p  (对)

    (a  -  b) % p = (a%p  - b%p) %p  (对)

    (a  *  b) % p = (a%p * b%p) %p  (对)

    (a  /  b) % p = (a%p / b%p) %p  (错)

    很容易就发现四则运算中,只有除法是不符合的,那么如果我们在做题时遇到了除法又要取余的时候,应该怎么办呢?

    下面我们就引入逆元这个概念a*x  ≡ 1 (mod p) (a和p互质)

    那么x就是a在模p意义下的逆元,一般用inv(a)表示

    那么前面这个式子就可以这么表示了(a  /  b) % p = (a * inv(a) ) % p = (a % p * inv(a) % p) % p

    下面来讲几个求逆元的方法

    1、费马相关

    根据逆元的定义 a*x  ≡ 1 (mod p)

    以及费马小定理 a^(p-1) ≡ 1 (mod p)

    那么我们两边同除a,就可以得到 a^(p-2) ≡ inv(a) (mod p)

    而这就是a的逆元,时间复杂度O(log p)

    2、递推求1-n的逆元

    设p=a*i+b,即a=p/i,b=p%i,那么 a*i+b ≡ 0 (mod p) 

    两边同时乘上 (i-1)*(b-1)

    就会得到 a*(b-1)+(i-1) ≡ 0 (mod p)

    移项得(i-1) ≡ -a*(b^-1) (mod p)

    代入前面设的值 (i-1) ≡ -(p/i)*inv(p%i) (mod p)

    即inv[i] = -(p/i) * inv[p%i]

    二、扩展欧几里得

    对于一个方程 ax + by = 1 当且仅当 a和b互质时才有解

    而这个的原型就是 ax+by=gcd(a,b) 而他的通解的解法就是扩欧

    因为gcd的辗转相除法 gcd(a,b)=gcd(b,a%b)

    所以以上那个方程通过变化可以变成 bx' + (a%b)y' = gcd(a,b)

    那么 ax+by = bx' + (a%b)y'

    通过移项可变成 ax+by = ay'+b(x'-(a)y')

    现在就可以很明显的得到一个递归式子 x=y',y=x'-(a)y'

    而求这个的方法则类似gcd的做法

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

      

    我们再回来看看求逆元的第三种方法

    3、扩欧相关

    根据逆元的定义 a*x  ≡ 1 (mod p)

    把它看成 a*x + p*y ≡ 1 (mod p)

    显然当且仅当 gcd(a, p) = 1 时存在一组解(x, y)满足条件,也就是存在a mod p的逆元

    证明如下:a*x % b + b*y % b = 1 % b

    a*x % b = 1 % b 转化为 a*x ≡ 1 (mod b)

    void exgcd(LL a, LL b, LL &x, LL &y, LL &d){
        if (b==0) {d=a; x=1;y=0; return;}
        exgcd(b,a%b,y,x,d); y-=x*(a/b);
    }
    LL inv(LL t, LL p){
        LL d,x,y; exgcd(t,p,x,y,d);
        return d==1?(x%p+p)%p:-1;
    }

    4、求阶乘的逆元

    因为 (a !) * x ≡ 1 (mod p)

    那么 (a-1) ! * a%p *x ≡ 1 (mod p)

    那么 (a-1) ! 的逆元就是 (a%p*x) ,就是a的阶乘的逆元 *a%p

    那么我们就可以先求出 n! 的逆元,然后就可以O(1) 逆推求其他阶乘的逆元了

  • 相关阅读:
    window忘记密码怎么办
    VS2015配置Andriod开发环境
    记一次 thread.blocked.count 线程过多的问题排查
    Spring的事务初见
    对mybatis的Handler 从使用角度介绍
    最简单的RPC框架实现
    记一次mybatis bindingexception 问题排查
    Java线程池—ThreadPool简介
    [springMvc] 源码分析笔记(二)
    [tomcat] tomcat简析(一)
  • 原文地址:https://www.cnblogs.com/logic-yzf/p/7793287.html
Copyright © 2011-2022 走看看