2023 寒假 第一周

106 阅读2分钟

乘法逆元:

常见于一个数对另一个数取模,但前者涉及一个除法,例如 A/B mod C,此时并不能将其视为(A mod C) /( B mod C ) mod C

由欧拉定理 
若正整数a,n互质,则对于任意正整数b
abab  mod  ϕ(n)  (mod  n)a^b \equiv a^{b\;mod\;\phi(n)}\;(mod\;n)

当gcd (a, b)=1时,a 在模 b 意义下的乘法逆元存在

拓展欧几里得定理

定理概述:对于不为0的整数a,b一定存在整数x,y使得

gcd(a,b)=ax+bygcd(a,b) = ax + by

我们只需递归该方程求出x即可得到a在模b意义下的逆元 这个方法单个查找效率似乎也还不错,比后面要介绍的大部分方法都要快(尤其对于 mod p 比较大的时候)。

而且这个做法还有个好处在于,当 a⊥p(互质),但 p 不是质数的时候也可以使用。

void exgcd(ll a, ll b, ll& x, ll& y)
{
	if (!b) { x = 1; y = 0; }
	else exgcd(b, a % b, y, x), y -= a / b * x;
}
ll Exgcd(ll a, ll b, ll& x, ll& y)//法二
{
    if(!b){ x = 1; y = 0; return a; }
    ll d = exgcd(b, a%b, x, y);
    ll z = x;
    x = y;  y = z - (a / b) * y;
    return d;
}
int main()
{
	ll a, p, x, y;
	exgcd(a, p, x, y);
	x = (x % p + p) % p;// x 是 a 在mod p 下的逆元
    /*        法二         */
    ll d = Exgcd(a, b, x, y);//求出ax + by = gcd(a, b);的一组特解并返回a,b的最大公约数d
}

快速幂

这个做法要利用 费马小定理

p为素数,a为正整数,且ap互质。则有a(p1)1  (mod  p)若p为素数,a为正整数,且a、p互质。 则有a ^{ (p−1) }≡ 1\;(mod\; p )
/*      注意: a为正整数   p为素数   且a,p互质  时才能使用          */
ll fpm(ll x, ll power, ll mod) 
{
    x %= mod;
    ll ans = 1;
    for (; power; power >>= 1, (x *= x) %= mod)
    	if(power & 1) (ans *= x) %= mod;
    return ans;
}
int main() 
{
	ll x = fpm(a, p - 2, p); //x为a在mod p意义下的逆元
}

线性算法

用于求一连串数字对于一个mod p的逆元。洛谷P3811

只能用这种方法,别的算法都比这些要求一串要慢。

首先我们有一个,111(mod  p)然后设p=ki+r,(1<r<i<p)也就是kp/i的商,r是余数。然后乘上i1,r1就可以得到:kr1+i10(mod  p)i1kr1(mod  p)i1pi(p  mod  i)1(mod  p)首先我们有一个,1^{-1}≡ 1 (mod\;p) \\ 然后设 p=k∗i+r,(1<r<i<p) 也就是 k 是 p/i 的商,r 是余数 。 然后乘上i−1,r−1就可以得到:\\ k∗r^{−1}+i^{−1} ≡ 0 (mod\;p)\\ i{−1} ≡ −k∗r^{−1}(mod\;p)\\ i^{−1}≡−\frac{p}{i}∗(p\;mod\;i)^{−1}(mod\;p)\\
inv[1] = 1;
for(int i = 1; i < p; ++ i)
    inv[i] = (p - p / i) * inv[p % i] % p;

阶乘逆元 O(n)求

因为有如下一个递推关系。

inv[i+1]=1(i+1)!inv[i+1](i+1)=1i!=inv[i]所以我们可以求出i,i!,1i!的取值了。然后这个也可以导出1i(mod  p)的取值,也就是1i!×(i1)!=1i(mod  p)inv[i+1]=\frac{1}{(i+1)!}\\ inv[i+1]∗(i+1)=\frac{1}{i!}=inv[i]\\ 所以我们可以求出 ∀i,i!,\frac{1}{i!} 的取值了。\\ 然后这个也可以导出 \frac{1}{i}(mod\;p) 的取值,也就是\\ \frac{1}{i!}×(i−1)!=\frac{1}{i}(mod\;p)