零、共识
a
∣
b
a\mid b
a∣b:a能整除b(
b
%
a
=
0
b\%a=0
b%a=0 )
a
∤
b
a\nmid b
a∤b:a不能整除b(
b
%
a
≠
0
b\%a\neq0
b%a=0 )
a
≡
b
(
m
o
d
m
)
a\equiv b(mod\ m)
a≡b(mod m):a与b模n同余(
a
%
n
=
b
%
n
a\%n=b\%n
a%n=b%n)
(
a
,
b
)
=
g
c
d
(
a
,
b
)
(a,b)=gcd(a,b)
(a,b)=gcd(a,b)
[
a
,
b
]
=
l
c
m
(
a
,
b
)
[a,b]=lcm(a,b)
[a,b]=lcm(a,b)
i
n
v
(
a
)
=
1
a
inv(a)= \frac{1}{a}
inv(a)=a1
充分必要条件:
a
⇔
b
a\Leftrightarrow b
a⇔b
一、定义及性质
1 什么是逆元
如果一个线性同余方程 a x ≡ 1 ( m o d b ) ax\equiv1(mod\ b) ax≡1(mod b),则称 x x x 为 a m o d b a\ mod\ b a mod b的逆元,记作 a − 1 a^{-1} a−1 。
2 整除的性质
- a ∣ b ⇔ − a ∣ b ⇔ a ∣ − b ⇔ ∣ a ∣ ∣ ∣ b ∣ a\mid b\Leftrightarrow -a\mid b\Leftrightarrow a\mid -b\Leftrightarrow|a|\mid|b| a∣b⇔−a∣b⇔a∣−b⇔∣a∣∣∣b∣
- a ∣ b , b ∣ c ⇒ a ∣ c a\mid b,b\mid c\Rightarrow a\mid c a∣b,b∣c⇒a∣c
- a ∣ b , a ∣ c ⇒ a ∣ ( b x + c y ) a\mid b,a\mid c \Rightarrow a\mid (bx+cy) a∣b,a∣c⇒a∣(bx+cy)
- a ∣ b , m ≠ 0 ⇒ m a ∣ m b a\mid b,m\neq0\Rightarrow ma\mid mb a∣b,m=0⇒ma∣mb
- m ∣ a b , ( a , b ) = 1 ⇒ m ∣ b m\mid ab,(a,b)=1\Rightarrow m\mid b m∣ab,(a,b)=1⇒m∣b
- a i ∣ b ( 1 ≤ i ≤ n ) ⇔ [ a 1 , a 2 … a n ∣ b a_i\mid b(1\le i\le n)\Leftrightarrow \lbrack a_1,a_2\ldots a_n \mid b ai∣b(1≤i≤n)⇔[a1,a2…an∣b
3 同余的性质
- 当 a ≡ b ( m o d b ) a\equiv b(mod\ b) a≡b(mod b) 时:
a ≡ a ( m o d b ) a\equiv a(mod\ b) a≡a(mod b) 自反
b ≡ a ( m o d b ) b\equiv a(mod\ b) b≡a(mod b) 对称
b ≡ c ( m o d b ) b\equiv c(mod\ b) b≡c(mod b) ⇒ a ≡ c ( m o d b ) \Rightarrow a\equiv c(mod\ b) ⇒a≡c(mod b) 传递
a + c ≡ b + c ( m o d b ) a+c\equiv b+c(mod\ b) a+c≡b+c(mod b) 同加
a × c ≡ b × c ( m o d b ) a\times c\equiv b\times c(mod\ b) a×c≡b×c(mod b) 同乘
a c ≡ b c ( m o d b ) a^c\equiv b^c(mod\ b) ac≡bc(mod b) 同幂
-
a m o d p = x , a m o d q = x , ( p , q ) = 1 ⇒ a m o d p q = x a\ mod\ p=x,a\ mod\ q=x,(p,q)=1\Rightarrow a\ mod\ pq=x a mod p=x,a mod q=x,(p,q)=1⇒a mod pq=x
-
d ≥ 1 , d ∣ m , a = b ( m o d m ) ⇒ a ≡ b ( m o d d ) d\ge1,d\mid m,a = b(mod\ m)\Rightarrow a\equiv b(mod\ d) d≥1,d∣m,a=b(mod m)⇒a≡b(mod d)
-
d ≠ 0 ⇒ a ≡ b ( m o d m ) ⇔ d a ≡ d b ( m o d ∣ d ∣ m ) d\neq0\Rightarrow a\equiv b(mod\ m)\Leftrightarrow da\equiv db(mod\ |d|m) d=0⇒a≡b(mod m)⇔da≡db(mod ∣d∣m)
-
c a ≡ c b ( m o d m ) ⇔ a ≡ b ( m o d m ( c , m ) ) ca\equiv cb(mod\ m)\Leftrightarrow a\equiv b(mod\ \frac{m}{(c,m)}) ca≡cb(mod m)⇔a≡b(mod (c,m)m)
4 费马小定理
如果 p p p 是一个质数,而整数 a a a 不是 p p p 的倍数,则 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1(mod\ p) ap−1≡1(mod p)。
5 逆元
根据费马小定理:
∵
a
p
−
1
%
p
=
1
\because a^{p-1}\%p=1
∵ap−1%p=1
∴
(
a
×
a
p
−
2
)
%
p
=
1
\therefore (a\times a^{p-2})\%p=1
∴(a×ap−2)%p=1
∵
1
%
p
=
1
\because 1\%p=1
∵1%p=1
∴
(
a
×
a
−
1
)
%
p
=
1
\therefore (a\times a^{-1})\%p=1
∴(a×a−1)%p=1
∴
a
−
1
=
a
p
−
2
\therefore a^{-1}=a^{p-2}
∴a−1=ap−2
二、实践
1 求逆元
1.1 题目
求 b = 1 0 9 + 7 b=10^9+7 b=109+7 时 a m o d b a\ mod\ b a mod b 的逆元( a − 1 a^{-1} a−1 )。
1.2 思路
直接用 a − 1 = a p − 2 a^{-1}=a^{p-2} a−1=ap−2 即可。
1.3 代码
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
using namespace std;
ll a;
const ll mod=1e9+7;
ll qpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1){
ans=ans*a%mod;
}
b>>=1;
a=a*a%mod;
}
return ans;
}
int main(){
cin>>a;
cout<<qpow(a,mod-2);
return 0;
}
2 线性求逆元
2.1 题目
给定 n , p n,p n,p ,求 1 1 1 到 n n n 所有整数在模 p p p 意义下的乘法逆元。
2.2 思路
以下除法都是向下取整。设:
k
=
p
i
,
j
=
p
m
o
d
i
k=\frac{p}{i},j=p\ mod\ i
k=ip,j=p mod i
能够得到:
p
=
k
i
+
j
p=ki+j
p=ki+j
带入同余式中:
p
≡
k
i
+
j
≡
0
(
m
o
d
p
)
p\equiv ki+j\equiv 0(mod\ p)
p≡ki+j≡0(mod p)
k
i
+
j
≡
0
(
m
o
d
p
)
ki+j\equiv 0(mod\ p)
ki+j≡0(mod p)
两边同时乘以i的逆元,得到:
k
j
−
1
+
i
−
1
≡
0
(
m
o
d
p
)
kj^{-1}+i^{-1}\equiv 0(mod\ p)
kj−1+i−1≡0(mod p)
移项:
i
−
1
≡
−
k
j
−
1
(
m
o
d
p
)
i^{-1}\equiv -kj^{-1}(mod\ p)
i−1≡−kj−1(mod p)
也就是:
i
−
1
≡
−
p
i
≡
(
p
−
p
i
)
j
−
1
≡
(
p
−
p
j
)
(
p
m
o
d
i
)
−
1
(
m
o
d
p
)
i^{-1}\equiv -\frac{p}{i}\equiv (p-\frac{p}{i})j^{-1}\equiv (p-\frac{p}{j})(p\ mod\ i)^{-1}(mod\ p)
i−1≡−ip≡(p−ip)j−1≡(p−jp)(p mod i)−1(mod p)
2.3 代码
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
using namespace std;
ll n,p;
ll inv[3000002];
int main(){
cin>>n>>p;
inv[1]=1;
cout<<1;pr;
for(int i=2;i<=n;i++){
inv[i]=(p-p/i)*inv[p%i]%p;
cout<<inv[i];pr;
}
return 0;
}
3 逆元求组合数
3.1 题目
求组合数 C n m C^m_n Cnm 对 1 0 9 + 7 10^9+7 109+7 取模的值。
3.2 思路
首先初始化 1 % m o d 1\% mod 1%mod ~ 1 0 6 % m o d 10^6\%mod 106%mod 的阶乘。由于组合数 C n m = n ! ( ( n − m ) ! × m ! ) C^m_n=\frac{n!}{((n-m)!\times m!)} Cnm=((n−m)!×m!)n! ,每次处理时使用公式 a − 1 = a p − 2 a^{-1}=a^{p-2} a−1=ap−2 即可,注意取模。
3.3 代码
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
using namespace std;
ll fac[1000005];
const ll mod=1e9+7;
ll qpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1){
ans=ans*a%mod;
}
b>>=1;
a=a*a%mod;
}
return ans;
}
void init() {
fac[0]=1;
for(int i=1;i<=1000000;i++) {
fac[i]=fac[i-1]*i%mod;
}
}
ll C(ll n,ll m) {
return fac[n]*qpow(fac[m]*fac[n-m]%mod,mod-2)%mod;
}
int main(){
init();
int t;
cin>>t;
while(t--) {
ll n,m;
cin>>n>>m;
cout<<C(n, m);pr;
}
return 0;
}