gcd 与 lcm
几个重要的公式:
gcd ( a , b ) = gcd ( a , a + b ) = gcd ( b , a m o d b ) \gcd(a,b)=\gcd(a,a+b)=\gcd(b,a\mod b) g cd( a , b ) = g cd( a , a + b ) = g cd( b , a mod b )
gcd ( k × a , k × b ) = k × gcd ( a , b ) \gcd(k\times a,k\times b)=k\times\gcd(a,b) g cd( k × a , k × b ) = k × g cd( a , b )
gcd ( a , b , c ) = gcd ( gcd ( a , b ) , c ) \gcd(a,b,c)=\gcd(\gcd(a,b),c) g cd( a , b , c ) = g cd( g cd( a , b ) , c )
若 gcd ( a , b ) = d ,则 gcd ( a / d , b / d ) = 1 ,互素 若\gcd(a,b)=d,则\gcd(a/d,b/d)=1,互素 若 g cd( a , b ) = d ,则 g cd( a / d , b / d ) = 1 ,互素
算数基本定理
任何一个大于1的自然数N,如果N不是质数,那么N可以唯一分解成有限个质数的乘积:n = p 1 c 1 p 2 c 2 . . . p m c m n=p_{1}^{c_{1}}p_{2}^{c_{2}}...p_{m}^{c_{m}} n = p 1 c 1 p 2 c 2 ... p m c m ,其中 p 为素数。
由此,设
a = p 1 c 1 p 2 c 2 . . . p m c m , b = p 1 f 1 p 2 f 2 . . . p m f m a=p_{1}^{c_{1}}p_{2}^{c_{2}}...p_{m}^{c_{m}},b=p_{1}^{f_{1}}p_{2}^{f_{2}}...p_{m}^{f_{m}} a = p 1 c 1 p 2 c 2 ... p m c m , b = p 1 f 1 p 2 f 2 ... p m f m ,
则
gcd ( a , b ) = p 1 min ( c 1 , f 1 ) p 2 min ( c 2 , f 2 ) . . . p m min ( c m , f m ) \gcd(a,b)=p_{1}^{\min(c_{1},f_{1})}p_{2}^{\min(c_{2},f_{2})}...p_{m}^{\min(c_{m},f_{m})} g cd( a , b ) = p 1 m i n ( c 1 , f 1 ) p 2 m i n ( c 2 , f 2 ) ... p m m i n ( c m , f m ) ,
l c m ( a , b ) = p 1 max ( c 1 , f 1 ) p 2 max ( c 2 , f 2 ) . . . p m max ( c m , f m ) lcm(a,b)=p_{1}^{\max(c_{1},f_{1})}p_{2}^{\max(c_{2},f_{2})}...p_{m}^{\max(c_{m},f_{m})} l c m ( a , b ) = p 1 m a x ( c 1 , f 1 ) p 2 m a x ( c 2 , f 2 ) ... p m m a x ( c m , f m ) 。
所以 l c m ( a , b ) = a × b / gcd ( a , b ) lcm(a,b)=a\times b/\gcd(a,b) l c m ( a , b ) = a × b / g cd( a , b ) 。
例题
给定
L , G L,G L , G ,问满足
g c d ( x , y , z ) = G gcd(x,y,z)=G g c d ( x , y , z ) = G 与
l c m ( x , y , z ) = L lcm(x,y,z)=L l c m ( x , y , z ) = L 的
x , y , z x,y,z x , y , z 有多少个。
注意问题变形为满足
gcd ( x / G , y / G , z / G ) = 1 , l c m ( x / G , y / G , z / G ) = L / G \gcd(x/G,y/G,z/G)=1,lcm(x/G,y/G,z/G)=L/G g cd( x / G , y / G , z / G ) = 1 , l c m ( x / G , y / G , z / G ) = L / G 的
( x / G ) , ( y / G ) , ( z / G ) (x/G),(y/G),(z/G) ( x / G ) , ( y / G ) , ( z / G ) 有多少个。
由算术基本定理,令
( x / G ) = p 1 i 1 , p 2 i 2 , p 3 i 3 (x/G) = p_{1}^{i_{1}},p_{2}^{i_{2}},p_{3}^{i_{3}} ( x / G ) = p 1 i 1 , p 2 i 2 , p 3 i 3 ,
( y / G ) = p 1 j 1 , p 2 j 2 , p 3 j 3 (y/G)=p_{1}^{j_{1}},p_{2}^{j_{2}},p_{3}^{j_{3}} ( y / G ) = p 1 j 1 , p 2 j 2 , p 3 j 3 ,
( z / G ) = p 1 k 1 , p 2 k 2 , p 3 k 3 (z/G)=p_{1}^{k_{1}},p_{2}^{k_{2}},p_{3}^{k_{3}} ( z / G ) = p 1 k 1 , p 2 k 2 , p 3 k 3 ,
( L / G ) = p 1 t 1 , p 2 t 2 , p 3 t 3 (L/G)=p_{1}^{t_{1}},p_{2}^{t_{2}},p_{3}^{t_{3}} ( L / G ) = p 1 t 1 , p 2 t 2 , p 3 t 3 。
根据
gcd \gcd g cd 与指数的关系,我们可以知道要使式子成立,则
min ( i 1 , j 1 , k 1 ) = 0 \min({i_{1},j_{1},k_{1}})=0 min ( i 1 , j 1 , k 1 ) = 0 满足互素性质,接下来分类讨论取值满足
max ( i 1 , j 1 , k 1 ) = t 1 \max({i_{1},j_{1},k_{1}})=t_{1} max ( i 1 , j 1 , k 1 ) = t 1 ,实际需要分解
G / L G/L G / L 的质因数。
裴蜀定理
若 a,b 为正整数,则有 x,y 使 ax+by=gcd(a,b)
推论:a 与 b 互素当且仅当 ax + by=1,也就是gca(a,b)=1
线性丢番图方程
也叫一元二次不定方程形如
a x + b y = c ax+by=c a x + b y = c ,
a , b a,b a , b 为常数,
x , y x,y x , y 为变量。
定理:设 d = gcd(a,b),若d 不能整除 c,方程无解;否则方程有特解 ( x 0 , y 0 ) (x_{0},y_{0}) ( x 0 , y 0 ) ,通解 x = x 0 + ( b / d ) n , y = y 0 − ( a / d ) n x=x_{0}+(b/d)n,y=y_{0}-(a/d)n x = x 0 + ( b / d ) n , y = y 0 − ( a / d ) n 。
如何求?
扩展欧几里得算法
先用扩展欧几里得求出
a x + b y = gcd ( a , b ) ax+by=\gcd(a,b) a x + b y = g cd( a , b ) 的特解
( x 0 , y 0 ) (x_{0},y_{0}) ( x 0 , y 0 ) ,令此式左右同乘
( c / g c d ( a , b ) ) (c/gcd(a,b)) ( c / g c d ( a , b )) 变为
a x 0 c / g c d ( a , b ) + b y 0 c / g c d ( a , b ) = c ax_{0}c/gcd(a,b)+by_{0}c/gcd(a,b)=c a x 0 c / g c d ( a , b ) + b y 0 c / g c d ( a , b ) = c ,所以
a x + b y = c ax+by=c a x + b y = c 的特解就是
x ′ = x 0 c gcd ( a , b ) , y ′ = y 0 c gcd ( a , b ) x^{'}=x_{0}c\gcd(a,b),y^{'}=y_{0}c\gcd(a,b) x ′ = x 0 c g cd( a , b ) , y ′ = y 0 c g cd( a , b ) 。
CPP int exgcd (int a,int b,int &x,int &y) {
if (!b){
x=1 ,y=0 ;
return a;
}
d = exgcd (b,a%b,y,x);
y -= a/b * x;
return d;
}
同余
一元线性同余方程
逆元
对于非零整数
a , m a,m a , m ,如果存在
b b b 使得
a b ≡ 1 ( m o d m ) ab\equiv 1\pmod m ab ≡ 1 ( mod m ) ,就称
𝑏 𝑏 b 是
a a a 在模
m m m 意义下的逆元。
这相当于说,
b b b 是线性同余方程
a x ≡ 1 ( m o d m ) ax\equiv 1\pmod m a x ≡ 1 ( mod m ) 的解。根据 线性同余方程 的性质可知,当且仅当
gcd ( a , m ) = 1 \gcd(a,m)=1 g cd( a , m ) = 1 ,即
a , m a,m a , m 互素时,逆元
a − 1 m o d m a^{-1}\bmod m a − 1 mod m 存在,且在模
m m m 的意义下是唯一的。
求解逆元的多种形式:
单个逆
e x g c d exgcd e xg c d :要求
gcd ( a , m ) = 1 \gcd(a,m)=1 g cd( a , m ) = 1
CPP void ex_gcd (int a, int b, int & x, int & y) {
if (!b) {
x = 1 ;
y = 0 ;
} else {
ex_gcd (b, a % b, y, x);
y -= a / b * x;
}
}
快速幂:要求
m m m 为素数
根据费马小定理
a ∗ a m − 2 = a m − 1 ≡ 1 ( m o d m ) a*a^{m-2}=a^{m-1}\equiv 1\pmod m a ∗ a m − 2 = a m − 1 ≡ 1 ( mod m )
以及逆元的唯一性可知,逆元
a − 1 m o d p a^{-1}\bmod p a − 1 mod p 就等于
a p − 2 m o d p a^{p-2}\bmod p a p − 2 mod p ,因此可以直接使用 快速幂 在
O ( log p ) O(\log p) O ( log p ) 时间内计算:
CPP int qpow (int a, int b, int m) {
long long res = 1 , po = a;
for (; b; b >>= 1 ) {
if (b & 1 ) res = res * po % m;
po = po * po % m;
}
return res;
}
int inverse (int a, int p) { return qpow (a, p - 2 , p); }
多个逆
线性递推求逆:
同余方程组
𝑥 ≡𝑎1(mod𝑛1)
𝑥 ≡𝑎2(mod𝑛2)
⋮
𝑥 ≡𝑎𝑘(mod𝑛𝑘)
求同余方程组的解
中国剩余定理 CRT
此方法只适用于模数互质的情况,步骤:
计算总模数 M M M = 各个模数之积
计算 m i = M n i m_{i}=\frac{M}{n_{i}} m i = n i M
e x g c d exgcd e xg c d 计算 m i m_{i} m i 的逆元
方程在模 M M M 意义下的唯一解:x = ∑ i = 1 n a i × m i × m i − 1 ( m o d M ) x=\sum_{i=1}^{n}a_{i}\times m_{i}\times m_{i}^{-1}(mod M) x = ∑ i = 1 n a i × m i × m i − 1 ( m o d M )
CPP for (int i=1 ;i<=n;i++){
read (a[i]); read (b[i]);
M = M * a[i];
}
for (int i=1 ;i<=n;i++){
__int128 m = M / a[i],x,y;
exgcd (m,a[i],x,y);
ans = (ans + b[i] * m * x % M) % M;
}
整除分块
有这样一个问题:
以 n=10 为例
i 1 2 3 4 5 6 7 8 9 10 ⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor ⌊ i n ⌋ 10 5 3 2 2 1 1 1 1 1
注意到
⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor ⌊ i n ⌋ 的值有重复连续的区间,这启示我们按
⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor ⌊ i n ⌋ 的值
分块。
接下来证明分块少于
2 n 2\sqrt n 2 n 种。
当
i < = n i <= \sqrt n i <= n 时,
⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor ⌊ i n ⌋ 的值大于等于
n \sqrt n n ,共
n \sqrt n n 个;当
i > n i > \sqrt n i > n 时,
⌊ n i ⌋ < n \lfloor\frac{n}{i}\rfloor < \sqrt n ⌊ i n ⌋ < n ,也有
n \sqrt n n 个。
当一个区间内的值为
k k k 时,区间右端点为
⌊ x k ⌋ \lfloor\frac{x}{k}\rfloor ⌊ k x ⌋ ,证明略。
CPP ll get (ll x) {
ll res = 0 ;
for (ll i=1 ,j;i<=x;i=j+1 ){
j = x / (x / i);
res += (x/i) * (j - i + 1 );
}
return res;
}
以 n=10 为例
i 1 2 3 4 5 6 7 8 9 10 ⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor ⌊ i n ⌋ 10 5 3 2 2 1 1 1 1 1 i × ⌊ n i ⌋ i\times \lfloor \frac{n}{i} \rfloor i × ⌊ i n ⌋ 10 10 9 12 10 6 7 8 9 10
相当于每个区间是一个首项为
⌊ x i ⌋ × i \lfloor\frac{x}{i}\rfloor\times i ⌊ i x ⌋ × i ,尾项为
⌊ x i ⌋ × ⌊ x k ⌋ \lfloor\frac{x}{i}\rfloor\times\lfloor\frac{x}{k}\rfloor ⌊ i x ⌋ × ⌊ k x ⌋ ,长度为
( r − l + 1 ) (r - l + 1) ( r − l + 1 ) ,公差为
⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor ⌊ i n ⌋ 的等差数列。
CPP ll get (ll x) {
ll res = 0 ;
for (ll i=1 ,j;i<=x;i=j+1 ){
ll k = x / i;
j = x / k;
res += k * (i + j) * (j - i + 1 ) / 2 ;
}
return res;
}
模拟赛遇到了,没做出来。
给定
a , b a,b a , b 两个序列,定义
c i = ∑ j = 1 i a ⌊ i j ⌋ × b i m o d j c_{i} = \sum_{j=1}^{i} a_{\lfloor\frac{i}{j}\rfloor} \times b_{i\mod j} c i = ∑ j = 1 i a ⌊ j i ⌋ × b i mod j ,求序列
c c c 。
和上面的结论一样,根据整除分块,
⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor ⌊ i n ⌋ 相同的
a a a 是连续的一段,且只有
s q r t n sqrt_{n} s q r t n 级别,注意到
i m o d j i \mod j i mod j 在这相同的一段中是公差为
⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor ⌊ i n ⌋ 的等差数列的形式,所以说我们就可以利用根号分治的思想,小于根号 k 的暴力计算,大于根号 k 的进行下标的等差数列前缀和预处理,利用整除分块快速计算。
-2025.11.18