本文是 NOI 一轮复习的第八篇,主要介绍了数论、线性代数、计算几何和其它数学知识。
正整数中的数论
主要是针对素数的研究。
素数与合数
如果一个数 x ( x ∈ N ) x(x\in\mathbb{N}) x ( x ∈ N ) 的约数仅有 1 1 1 和它本身,那么就称 x x x 是质数(素数),特别地,0 0 0 和 1 1 1 不是质数,如果一个自然数不是质数,他就是合数。
可以用线性筛在 O ( n ) O(n) O ( n ) 的时间内筛出所有质数,用 O ( r + ( r − l + 1 ) log ( r − l + 1 ) ) O(\sqrt{r}+(r-l+1)\log(r-l+1)) O ( r + ( r − l + 1 ) log ( r − l + 1 )) 的时间筛出区间内的所有质数。
p p p 进赋值序列是刻画正整数的重要方式。可以将正整数表示到 p p p 维空间上。
大质因数
一个数最多只有一个 ≥ v \ge \sqrt{v} ≥ v 的质数因子,这个思路非常经典。
[NOI2015] 寿司晚宴 。最暴力的做法就是设 f S 1 , S 2 f_{S_1,S_2} f S 1 , S 2 代表两人选的质因数状压后分别为 S 1 , S 2 S_1,S_2 S 1 , S 2 ,发现 n ≤ 500 n\le 500 n ≤ 500 ,比 19 19 19 大的质因数最多出现一次,可以单独记录这个大质因数,然后把每一个有这个大质因数的寿司设为一组,在这一组进行转移时另记 g 1 , g 2 g_1,g_2 g 1 , g 2 分别代表只允许这两个人其中一个吃有这个大质因数的寿司,最后合并答案的时候还要减去最初的 f f f ,因为两个人都不吃的算了两次。代码 。
整除性
研究整除相关的数论。
数论分块
数论分块 。⌊ n i ⌋ \left\lfloor\frac{n}{i}\right\rfloor ⌊ i n ⌋ 只有 O ( n ) O(\sqrt{n}) O ( n ) 中不同的取值,并且每一种取值都是一个连续的区间。
比如光速幂是利用这一点来实现的,这个技巧也可以在 O ( n ) O(\sqrt{n}) O ( n ) 时间内枚举到所有区间。
最经典的应用就是快速计算 ∑ i = 1 n f ( i ) g ( ⌊ n i ⌋ ) \sum_{i=1}^n f(i)g\left(\left\lfloor\frac{n}{i}\right\rfloor\right) ∑ i = 1 n f ( i ) g ( ⌊ i n ⌋ ) ,需要 O ( 1 ) O(1) O ( 1 ) 计算 ∑ i = l r f ( i ) \sum_{i=l}^{r}f(i) ∑ i = l r f ( i ) ,然后将 g g g 相同的打包计算。
使得 ⌊ n i ⌋ = ⌊ n j ⌋ \lfloor\frac{n}{i}\rfloor=\lfloor\frac{n}{j}\rfloor ⌊ i n ⌋ = ⌊ j n ⌋ 成立的最大满足 i ≤ j ≤ n i\le j\le n i ≤ j ≤ n 的块的右端点为 ⌊ n ⌊ n i ⌋ ⌋ \left\lfloor\cfrac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloor ⌊ ⌊ i n ⌋ n ⌋ 。为什么?令 k = ⌊ n i ⌋ k=\lfloor\frac{n}{i}\rfloor k = ⌊ i n ⌋ ,可知 k ≤ n i k\le \frac{n}{i} k ≤ i n ,那么 ⌊ n k ⌋ ≥ i \lfloor\frac{n}{k}\rfloor\ge i ⌊ k n ⌋ ≥ i ,所以 j = n i j=\frac{n}{i} j = i n 。时间复杂度 O ( n ) O(\sqrt{n}) O ( n ) 。
欧几里德算法
辗转相减法可以用来求解两个数的 gcd \gcd g cd :
int gcd ( int a, int b) {
if ( a == b) return a;
if ( ! a || ! b) return a | b;
if ( ! ( a & 1 ) ) {
if ( b & 1 ) return gcd ( a >> 1 , b) ;
return gcd ( a >> 1 , b >> 1 ) << 1 ;
}
if ( ! ( b & 1 ) ) return gcd ( a, b >> 1 ) ;
if ( a > b) return gcd ( ( a - b) >> 1 , b) ;
return gcd ( ( b - a) >> 1 , a) ;
}
辗转相减(除)是一个非常重要的结构,出现时往往伴随着与 gcd \gcd g cd 相关的结论。
类欧几里德算法
万能欧几里德算法
数论函数
定义域为整数的函数是数论函数,一般我们研究数论函数中的积性函数。对于所有积性函数 f f f ,都有 f ( 1 ) = 1 f(1)=1 f ( 1 ) = 1 。
常见积性函数:
单位函数 ϵ ( n ) = [ n = 1 ] \epsilon(n)=[n=1] ϵ ( n ) = [ n = 1 ] ,是完全积性函数。
常数函数 1 ( n ) = 1 1(n)=1 1 ( n ) = 1 ,是完全积性函数。
恒等函数 id k ( n ) = n k \operatorname{id}_k(n)=n^k id k ( n ) = n k ,是完全积性函数,当 k = 1 k=1 k = 1 时可以省略不写。
除数函数 σ k ( n ) = ∑ d ∣ n d k \sigma_k(n)=\sum_{d\mid n}d^k σ k ( n ) = ∑ d ∣ n d k 。这样的话,σ 0 ( n ) = τ ( n ) \sigma_0(n)=\tau(n) σ 0 ( n ) = τ ( n ) ,σ 1 ( n ) \sigma_1(n) σ 1 ( n ) 代表约数和,有 σ k ( n ) = ∏ i = 1 s ( ∑ j = 0 α i p i j k ) = ∏ i = 1 s σ k ( p i α i ) \sigma_k(n)=\prod_{i=1}^s\left(\sum_{j=0}^{\alpha_i}p_i^{jk}\right)=\prod_{i=1}^s\sigma_k(p_i^{\alpha_i}) σ k ( n ) = ∏ i = 1 s ( ∑ j = 0 α i p i jk ) = ∏ i = 1 s σ k ( p i α i ) 。
欧拉函数,φ ( n ) \varphi(n) φ ( n ) 代表 1 ∼ n 1\sim n 1 ∼ n 中与 n n n 互质的数的个数。
本质不同质因子个数函数 ω ( n ) = ∑ p [ p ∣ n ] \omega(n)=\sum_{p}[p\mid n] ω ( n ) = ∑ p [ p ∣ n ] 。
线性筛可以计算所有的积性函数(前提是可以快速求出 f ( p k + 1 ) f(p^{k+1}) f ( p k + 1 ) ,只需要记录 l o w low l o w 代表最小质因子的最高次幂:
for ( int i = 2 ; i <= n; i++ ) {
if ( ! vis[ i] ) prime[ ++ tot] = i, f[ i] = . . . , low[ i] = i;
for ( int j = 1 ; j <= tot && i * prime[ j] <= n; j++ ) {
vis[ i * prime[ j] ] = 1 ;
if ( i % prime[ j] == 0 ) {
low[ i * prime[ j] ] = low[ i] * prime[ j] ;
if ( i == low[ i] ) f[ i * prime[ j] ] = . . . ;
else f[ i * prime[ j] ] = f[ i / low[ i] ] * f[ low[ i] * prime[ j] ] ;
break ;
}
low[ i * prime[ j] ] = prime[ j] ;
f[ i * prime[ j] ] = f[ i] * f[ prime[ j] ] ;
}
}
狄利克雷卷积是数论函数的基本运算。定义:
h ( n ) = ∑ d ∣ n f ( d ) g ( n d ) h(n)=\sum_{d\mid n}f(d)g\left(\frac{n}{d}\right)
h ( n ) = d ∣ n ∑ f ( d ) g ( d n )
简记为 h = f ∗ g h=f*g h = f ∗ g 。
狄利克雷卷积具有交换律、结合律和分配律。
首先,ϵ ∗ f = f \epsilon*f=f ϵ ∗ f = f 。因此单位函数 ϵ \epsilon ϵ 为狄利克雷卷积的单位元 ,那么就可以定义数论函数的逆元 f − 1 f^{-1} f − 1 ,满足 f ∗ f − 1 = ϵ f*f^{-1}=\epsilon f ∗ f − 1 = ϵ 。
一个 f f f 存在逆元,当且仅当 f ( 1 ) ≠ 0 f(1)\ne 0 f ( 1 ) = 0 ,并且逆元唯一。f = g f=g f = g 的充要条件是 f ∗ h = g ∗ h ( h ( 1 ) ≠ 1 ) f*h=g*h(h(1)\ne 1) f ∗ h = g ∗ h ( h ( 1 ) = 1 ) 。这样一来有 g ( n ) = − ∑ d ∣ n , d ≠ n g ( d ) f ( n d ) f ( 1 ) g(n) = -\cfrac{\sum\limits_{d \mid n, d \neq n} g(d)f\left(\dfrac n d\right)} {f(1)} g ( n ) = − f ( 1 ) d ∣ n , d = n ∑ g ( d ) f ( d n ) 。
积性函数的狄利克雷卷积是积性函数,积性函数的逆元也是积性函数。
以下是一些常用的狄利克雷卷积:
1 ∗ 1 = τ 1*1=\tau 1 ∗ 1 = τ ,
φ ∗ 1 = id \varphi *1=\operatorname{id} φ ∗ 1 = id 。
任意数论函数 f f f 卷常数函数 1 1 1 等价于做 f f f 的狄利克雷前缀和 ,即:g = f ∗ 1 , g ( n ) = ∑ d ∣ n f ( d ) g=f*1,g(n)=\sum_{d\mid n}f(d) g = f ∗ 1 , g ( n ) = ∑ d ∣ n f ( d ) 。含义是对每个 n n n 计算给定数论函数在其所因数处的取值和。
将每个数写成无穷序列 a n = { c 1 , c 2 , ⋯ } a_n=\{c_1,c_2,\cdots\} a n = { c 1 , c 2 , ⋯ } 表示 n = ∏ p i c i n=\prod p_i^{c_i} n = ∏ p i c i 。由于 x ∣ y x\mid y x ∣ y 的充要条件为 a x ( c i ) ≤ a y ( c i ) a_x(c_i)\le a_y(c_i) a x ( c i ) ≤ a y ( c i ) ,因此 f ∗ 1 f*1 f ∗ 1 可以看成对下标做其无穷序列的高维前缀和。
模板 ,这里是对 a a a 做狄利克雷前缀和,本质上是分组背包,每个质数是一组,每组的体积是 p k p^k p k ,代码 。
欧拉函数
欧拉函数,即 φ ( n ) \varphi(n) φ ( n ) ,代表 1 ∼ n 1\sim n 1 ∼ n 中与 n n n 互质的数的个数。
设 n = ∏ p i k i n=\prod p_i^{k_i} n = ∏ p i k i ,则有:
φ ( n ) = n ∏ ( 1 − 1 p i ) = n ∏ p i − 1 p i \varphi(n)=n\prod(1-\cfrac{1}{p_i})=n\prod \cfrac{p_i-1}{p_i}
φ ( n ) = n ∏ ( 1 − p i 1 ) = n ∏ p i p i − 1
欧拉反演:n = ∑ d ∣ n φ ( d ) n = \sum_{d\mid n} \varphi(d) n = ∑ d ∣ n φ ( d ) 。
莫比乌斯函数
我们定义莫比乌斯函数:
μ ( n ) = { 1 , n = 1 , 0 , ∃ d > 1 , d 2 ∣ n , ( − 1 ) ω ( n ) , o t h e r w i s e . \mu(n)=\begin{cases}1,&n=1,\\0,&\exists d>1,d^{2}\mid n, \\(-1)^{\omega(n)},&\mathrm{otherwise}. \end{cases}
μ ( n ) = ⎩ ⎨ ⎧ 1 , 0 , ( − 1 ) ω ( n ) , n = 1 , ∃ d > 1 , d 2 ∣ n , otherwise .
实际上它是在对 N \mathbb{N} N 做容斥。设 g ( n ) = ∑ n ∣ d f ( d ) g(n)=\sum_{n\mid d} f(d) g ( n ) = ∑ n ∣ d f ( d ) ,已知 g g g ,要求 f ( 1 ) f(1) f ( 1 ) 。f ( 1 ) f(1) f ( 1 ) 等于 g g g 在 1 1 1 的倍数处取的取值和,减去质数处的取值和,但是多减了两个质数乘积的地方,因此还要加回来。这就是容斥原理,容斥系数是 ( − 1 ) ω ( n ) (-1)^{\omega(n)} ( − 1 ) ω ( n ) 。
它不仅是积性函数,还满足:
∑ d ∣ n μ ( d ) = { 1 , n = 1 , 0 , n ≠ 1. \sum_{d\mid n}\mu(d)=\begin{cases}
1,&n=1,\\
0,&n\neq 1.
\end{cases}
d ∣ n ∑ μ ( d ) = { 1 , 0 , n = 1 , n = 1.
上述式子描述的其实是 μ ∗ 1 = ϵ \mu*1=\epsilon μ ∗ 1 = ϵ ,也就是说 μ \mu μ 是 1 1 1 的逆元。这是莫比乌斯函数最重要的性质,其引出了性质:∑ d ∣ n μ ( d ) = [ n = 1 ] \sum_{d\mid n}\mu(d)=[n=1] ∑ d ∣ n μ ( d ) = [ n = 1 ] ,我们可以将这个艾弗森括号转化为和式,这样更加方便计算。两者的转化称之为莫比乌斯反演。
莫比乌斯反演有以下结论:
若 g = f ∗ 1 g=f*1 g = f ∗ 1 ,则 f = g ∗ μ f=g*\mu f = g ∗ μ 。
若 g ( n ) = ∑ n ∣ d f ( d ) g(n)=\sum_{n\mid d}f(d) g ( n ) = ∑ n ∣ d f ( d ) ,则 f ( n ) = ∑ n ∣ d μ ( d n ) g ( d ) f(n)=\sum_{n\mid d} \mu\left(\dfrac d n\right) g(d) f ( n ) = ∑ n ∣ d μ ( n d ) g ( d ) 。这也被称为莫比乌斯变换 ,实际上就是把上面那一条给写出来。
由于 φ ∗ 1 = id \varphi * 1 = \operatorname{id} φ ∗ 1 = id ,因此 id ∗ μ = φ \operatorname{id} * \mu =\varphi id ∗ μ = φ 。
一个常见的应用是,[ gcd ( i , j ) = 1 ] = ∑ d ∣ gcd ( i , j ) μ ( d ) [\gcd(i,j)=1]=\sum_{d\mid \gcd(i,j)}\mu(d) [ g cd( i , j ) = 1 ] = ∑ d ∣ g c d ( i , j ) μ ( d ) 。虽然看起来这像是废话,但这一步将 i , j i,j i , j 互质转化为了枚举 gcd ( i , j ) \gcd(i,j) g cd( i , j ) 的约数 d d d 。如果 i , j i,j i , j 同样需要枚举,那么枚举 d d d 并计算合法的 i , j i,j i , j 个数(当且仅当 d ∣ i , d ∣ j d\mid i,d\mid j d ∣ i , d ∣ j )即可。具体来说:
∑ i = 1 n ∑ j = 1 m [ gcd ( i , j ) = 1 ] = ∑ i = 1 n ∑ j = 1 m ∑ d ∣ gcd ( i , j ) μ ( d ) = ∑ d = 1 min ( n , m ) μ ( d ) ∑ i = 1 n ∑ j = 1 m [ d ∣ i ∧ d ∣ j ] = ∑ d = 1 min ( n , m ) μ ( d ) ⌊ n d ⌋ ⌊ m d ⌋ \begin{aligned}
\sum\limits_{i = 1} ^ n \sum\limits_{j = 1} ^ m [\gcd(i, j) = 1] & = \sum\limits_{i = 1} ^ n \sum\limits_{j = 1} ^ m \sum\limits_{d\mid \gcd(i, j)} \mu(d) \\
& = \sum\limits_{d = 1} ^ {\min(n, m)} \mu(d) \sum\limits_{i = 1} ^ n \sum\limits_{j = 1} ^ m [d\mid i\land d\mid j] \\
& = \sum\limits_{d = 1} ^ {\min(n, m)} \mu(d) \left\lfloor \dfrac n d \right\rfloor \left\lfloor \dfrac m d \right\rfloor \\
\end{aligned}
i = 1 ∑ n j = 1 ∑ m [ g cd( i , j ) = 1 ] = i = 1 ∑ n j = 1 ∑ m d ∣ g c d ( i , j ) ∑ μ ( d ) = d = 1 ∑ m i n ( n , m ) μ ( d ) i = 1 ∑ n j = 1 ∑ m [ d ∣ i ∧ d ∣ j ] = d = 1 ∑ m i n ( n , m ) μ ( d ) ⌊ d n ⌋ ⌊ d m ⌋
就可以直接使用数论分块在 O ( n + m ) O(\sqrt{n}+\sqrt{m}) O ( n + m ) 的时间内计算。
杜教筛
我们要求积性函数 f f f 的前缀和,设 S ( n ) = ∑ i = 1 n f i S(n)=\sum_{i=1}^{n}f_i S ( n ) = ∑ i = 1 n f i ,再找一个积性函数 g g g ,考虑它们的狄利克雷卷积的前缀和:
∑ i = 1 n ∑ d ∣ i f ( d ) g ( i d ) = ∑ d = 1 n g ( d ) ∑ i = 1 ⌊ n d ⌋ f ( i ) = ∑ d = 1 n g ( d ) S ( ⌊ n d ⌋ ) \begin{aligned}
&\sum_{i=1}^{n} \sum_{d\mid i} f(d)g\left(\frac i d\right)\\
=&\sum_{d=1}^n g(d)\sum_{i=1}^{\left\lfloor\frac n d\right\rfloor} f(i)\\
=&\sum_{d=1}^n g(d)S\left(\left\lfloor\frac n d\right\rfloor\right)
\end{aligned}
= = i = 1 ∑ n d ∣ i ∑ f ( d ) g ( d i ) d = 1 ∑ n g ( d ) i = 1 ∑ ⌊ d n ⌋ f ( i ) d = 1 ∑ n g ( d ) S ( ⌊ d n ⌋ )
而我们有:
g ( 1 ) S ( n ) = ∑ i = 1 n g ( i ) S ( ⌊ n i ⌋ ) − ∑ i = 2 n g ( i ) S ( ⌊ n i ⌋ ) = ∑ i = 1 n ( f ∗ g ) ( i ) − ∑ i = 2 n g ( i ) S ( ⌊ n i ⌋ ) \begin{aligned}
g(1)S(n)&=\sum \limits _{i=1}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor) - \sum \limits _{i=2}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor)\\
&=\sum\limits_{i=1}^{n}(f*g)(i) - \sum \limits _{i=2}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor)
\end{aligned}
g ( 1 ) S ( n ) = i = 1 ∑ n g ( i ) S (⌊ i n ⌋) − i = 2 ∑ n g ( i ) S (⌊ i n ⌋) = i = 1 ∑ n ( f ∗ g ) ( i ) − i = 2 ∑ n g ( i ) S (⌊ i n ⌋)
时间复杂度为 O ( n 3 4 ) O(n^{\frac 3 4}) O ( n 4 3 ) ,我们先线性筛出前 m m m 个的答案,那么 m = n 2 3 m=n^{\frac 2 3} m = n 3 2 时,时间复杂度为 O ( n 2 3 ) O(n^{\frac 2 3}) O ( n 3 2 ) 。
模板 。有 μ ∗ 1 = ϵ , φ ∗ 1 = id \mu * 1 =\epsilon,\varphi * 1 =\operatorname{id} μ ∗ 1 = ϵ , φ ∗ 1 = id ,那么直接杜教筛即可。代码 。
Min_25 筛
例题
巩固一些基础内容。
[CF1656H] Equal LCM Subsets
Portal .
从质因数幂次的角度考虑,思考哪些是集合中不能要的地雷。
如果 a i a_i a i 不能留在集合中,那么它至少有一个质因子的幂次比 b b b 中其它所有数都大。也就是说,如果 gcd a i gcd ( a i , b j ) > 1 \gcd \cfrac{a_i}{\gcd(a_i,b_j)}>1 g cdg cd( a i , b j ) a i > 1 ,那么 a i a_i a i 就该被从集合中删除。相当于单点修改,查询全局 gcd \gcd g cd ,这个过程只能进行 O ( n + m ) O(n+m) O ( n + m ) 轮,线段树直接维护,每轮修改是 O ( ( n + m ) log ( n + m ) ) O((n+m)\log (n + m)) O (( n + m ) log ( n + m )) 的,可以接受。代码 。
* [Luogu P5435] 基于值域预处理的快速 GCD
Portal .
模意义下的数论
尽管数论相关的题目似乎已经退出环境,但是本身还是比较有意思的。
拉格朗日定理 :在模 p p p 意义下,最高次项系数非 0 0 0 的 n n n 次多项式至多有 n n n 个根。
线性同余方程组
可以使用 CRT 解决模数互质的情况,exCRT 解决模数不互质的情况。
{ x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) ⋯ x ≡ a 3 ( m o d m 3 ) \begin{cases}
x\equiv a_1 \pmod {m_1}\\
x\equiv a_2 \pmod {m_2}\\
\cdots\\
x\equiv a_3 \pmod {m_3}\\
\end{cases}
⎩ ⎨ ⎧ x ≡ a 1 ( mod m 1 ) x ≡ a 2 ( mod m 2 ) ⋯ x ≡ a 3 ( mod m 3 )
模数互质
设 M = ∏ i = 1 n m i , M i = m ÷ m i M=\prod_{i=1}^{n}m_i,M_i=m\div m_i M = ∏ i = 1 n m i , M i = m ÷ m i ,t i t_i t i 是线性同余方程 M i t i ≡ 1 ( m o d m i ) M_it_i\equiv 1 \pmod{m_i} M i t i ≡ 1 ( mod m i ) 的一个解,也就是说 t i t_i t i 是 M i M_i M i 模 m i m_i m i 的逆元(显然 M i ⊥ m i M_i \perp m_i M i ⊥ m i 当且仅当 m i m_i m i 两两互质),那么 x = ∑ i = 1 n a i M i t i + k M x=\sum_{i=1}^{n}a_iM_it_i + kM x = ∑ i = 1 n a i M i t i + k M ,最小非负整数解需要求 ∑ i = 1 n a i M i t i m o d M \sum_{i=1}^{n}a_iM_it_i\bmod M ∑ i = 1 n a i M i t i mod M 。
i64 CRT ( void ) {
i64 ans = 0 , x;
for ( int i = 1 ; i <= n; ++ i) {
M[ i] = mm / m[ i] ;
t[ i] = inv ( M[ i] , m[ i] ) ;
ans = ( ans + a[ i] * M[ i] * t[ i] ) % mm;
}
return ( ans % mm + mm) % mm;
}
模数不互质
考虑如何合并两个方程组。我们先假定一定可以合并,然后看看什么时候合并之后的解是 ∅ \varnothing ∅ 。
这玩意儿等价于 a = k 1 m 1 + r 1 = k 2 m 2 + r 2 ⟹ k 1 m 1 − k 2 m 2 = r 2 − r 1 a=k_1m_1+r_1=k_2m_2+r_2 \Longrightarrow k_1m_1-k_2m_2=r_2-r_1 a = k 1 m 1 + r 1 = k 2 m 2 + r 2 ⟹ k 1 m 1 − k 2 m 2 = r 2 − r 1 。这个熟悉!二元一次不定方程!直接使用 exgcd
计算即可。
于是:
如果 gcd ( m 1 , m 2 ) ∣ ( r 2 − r 1 ) \gcd(m_1,m_2)\mid (r_2-r_1) g cd( m 1 , m 2 ) ∣ ( r 2 − r 1 ) ,那么可以合并;
否则,exCRT 是无解的。
现在有引理:合并之后的模数是原来两个模数的 lcm
。
具体来说,设当前合并的余数为 M M M ,当前答案为 a n s ans an s ,那么任意一个 a n s + M x ans+Mx an s + M x 都满足答案,我们需要找到一个最小的 x x x 使得 a n s + M x ≡ a i ( m o d m i ) ans+Mx\equiv a_i\pmod {m_i} an s + M x ≡ a i ( mod m i ) ,可以使用扩展欧几里得来解决。
i64 exCRT ( void ) {
i64 M = 1 , ans = 0 ;
for ( int i = 1 ; i <= n; ++ i) {
i64 b = B[ i] , x, y, c = ( A[ i] - ans + b) % b;
i64 g = exgcd ( M, b, x, y) ;
if ( c % g != 0 ) return - 1 ;
x = ( __int128) x * ( c / g) % ( b / g) ;
ans = ans + M * x;
M = b / g * M;
ans %= M;
}
return ( ans % M + M) % M;
}
如果模数不是质数,那么可以使用 exCRT 合并。
阶与原根
例题
巩固一些基础内容。
[CF1848E] Vika and Stone Skipping
Portal .
如果跳 g g g 次,需要满足:
2 x ∏ X i = ( 2 f − g + 1 ) g 2x\prod X_i=(2f-g+1)g
2 x ∏ X i = ( 2 f − g + 1 ) g
求的就是 2 x ∏ X i 2x\prod X_i 2 x ∏ X i 的奇因数个数。提前将 x x x 除掉其 lowbit \operatorname{lowbit} lowbit 即可直接统计其因数。
直接维护即可。注意模数过小时逆元的爆炸问题。代码 。
[NOI2018] 屠龙勇士
Portal .
由于我们选择的武器是固定的,所以实际上依然是 exCRT,只不过方程换成了 b x ≡ a ( m o d p ) bx\equiv a\pmod p b x ≡ a ( mod p ) 。这样是一样的,设当前合并的模数为 M M M ,答案为 a n s ans an s ,那么下一个合并要满足 b ( a n s + M x ) ≡ a ( m o d p ) b(ans+Mx)\equiv a\pmod p b ( an s + M x ) ≡ a ( mod p ) ,也就是 b M x − p y = a − b × a n s bMx-py=a-b\times ans b M x − p y = a − b × an s 。
注意一个细节:解出来的解必须能将龙打掉,也就是能将血打成小于等于 0 0 0 ,否则即使满足同余方程也没用。记录一个能把血量打成负数的最小攻击次数,然后如果答案小于这个攻击次数,答案就加上还需要打的次数。代码 。
[CF338D] GCD Table
Portal .
首先如果有解,那么那个 x x x 应该满足 lcm ( a 1 , a 2 , ⋯ , a k ) ∣ x \operatorname{lcm}(a_1,a_2,\cdots,a_k) \mid x lcm ( a 1 , a 2 , ⋯ , a k ) ∣ x 。实际上 x x x 就应该等于 lcm \operatorname{lcm} lcm ,因为如果增加倍数,y y y 的构造只会变得更加困难。
这样我们只需要满足 a i ∣ y + i − 1 a_i\mid y+i-1 a i ∣ y + i − 1 ,exCRT 求一下即可。代码 。
线性代数
概念
高斯消元法
我们可以使用高斯消元以 O ( n 3 ) O(n^3) O ( n 3 ) 的时间求解方程组的解。具体来说就是一个一个地加减消元,转化成上三角形式,然后再代入即可。
线性基
对于异或线性基,我们使用贪心法构建:
void insert ( i64 x) {
for ( int i = 50 ; i >= 0 ; -- i)
if ( x & ( 1ll << i) ) {
if ( ! p[ i] ) { p[ i] = x; ++ cnt; break ; }
else x ^= p[ i] ;
}
}
i64 askmx ( void ) {
i64 ans = 0 ;
for ( int i = 50 ; i >= 0 ; -- i)
if ( ( ans ^ p[ i] ) > ans) ans ^= p[ i] ;
return ans;
}
最小异或值是 min { p i } \min\{p_i\} min { p i } 。
线性基的合并直接暴力合并即可。
LGV 引理
对于一个 DAG,
简单计算几何
数学杂项
连分数
群论入门
博弈论
博弈论主要研究一些有竞争或对抗性质的对象,在一定规则下/产生的各种行为。
对于公平组合游戏,我们通常会选择计算 SG 函数;对于非公平游戏,我们会选择推导一些性质。
概念
我们从 Nim 游戏开始研究。有 n n n 堆石子,每人每次可从任意一堆石子里取出正整数枚石子扔掉,谁不能动谁就输了。
我们将每个状态视作一个节点,那么博弈情况就可以刻画成一张有向图。不难发现,异或和为 0 0 0 时先手必败。
大部分的公平组合游戏(所有玩家都可以操作对方能操作的东西)都可以转换为有向图游戏,对于状态 x x x 和它的 k k k 个后继状态 y 1 , ⋯ , y k y_1,\cdots,y_k y 1 , ⋯ , y k ,定义 SG 函数为:
SG ( x ) = mex { SG ( y 1 ) , SG ( y 2 ) , … , SG ( y k ) } \operatorname{SG}(x)=\operatorname{mex}\{\operatorname{SG}(y_1), \operatorname{SG}(y_2), \ldots, \operatorname{SG}(y_k)\}
SG ( x ) = mex { SG ( y 1 ) , SG ( y 2 ) , … , SG ( y k )}
对于由 n n n 个有向图游戏组成的组合游戏,当且仅当 ⊕ SG ( s ) ≠ 0 \oplus \operatorname{SG}(s)\ne 0 ⊕ SG ( s ) = 0 的时候,先手必胜,称之为 P 态。也就是说,SG ( x ) = 0 \operatorname{SG}(x)=0 SG ( x ) = 0 是必败态 ,称之为 N 态。
SG 定理 :一个游戏的 SG 值是其所有子游戏的 SG 值的异或和,这可以说明 Nim 游戏结论的由来。
[HNOI2007] 分裂游戏 。终止状态是所有豆子在 n n n 号瓶子,而每个豆子是独立的,直接暴力 DP 即可。代码 。
Anti-SG 定理
如果不能动的人获胜,那么这个游戏叫做反常游戏。同样的,有判断必胜条件的 Anti-SG 定理:
如果游戏的 SG 值为 0 0 0 ,那么所有子游戏的 SG 值都不超过 1 1 1 时先手必胜(还是要异或值为 0 0 0 );
如果游戏的 SG 值不是 0 0 0 ,那么至少有一个子游戏的 SG 值超过 1 1 1 时先手必胜。其在决策过程中可以转化为上述情况。
模板 。
经典博弈模型
博弈论中有一些特别经典的问题,我们来介绍一些。
威佐夫博弈
Portal .
两堆石子,可以取一堆中的任意个,也可以在两堆中都取 x x x 个。
我们可以发现以下状态是先手必败的:
( 0 , 0 ) (0, 0) ( 0 , 0 ) ,
( 1 , 2 ) (1, 2) ( 1 , 2 ) ,
( 3 , 5 ) (3, 5) ( 3 , 5 ) ,
( 4 , 7 ) (4, 7) ( 4 , 7 ) ,
( 6 , 10 ) (6, 10) ( 6 , 10 ) ,
( 8 , 13 ) (8, 13) ( 8 , 13 ) 。
两者的差是自然数列,第一个数是之前所有新出现的数是之前出现数的 mex。可以证明结论是 a = ⌊ ( b − a ) × 5 + 1 2 ⌋ a=\left\lfloor (b-a)\times \cfrac{\sqrt{5}+1}{2}\right\rfloor a = ⌊ ( b − a ) × 2 5 + 1 ⌋ 时先手必败。
公平组合
博弈论除了 SG 定理外,剩下的内容几乎全部基于 DP。有时候通过打表来寻找 SG 函数的规律也是一个不错的选择。
[CF768E] Game of Stones
Portal .
可以考虑一个石堆会被取多少次,发现是从 1 1 1 开始依次取,然后就转成了正常的 Nim 游戏。代码 。
[HNOI2014] 江南乐
Portal .
考虑枚举所有的 m m m ,那么可以计算所有 n n n 的 SG 值。发现整除分块可以优化枚举 m m m 这个过程,因为 n / m n/m n / m 和 n / m + 1 n/m+1 n / m + 1 必有一个奇偶性不变。代码 。
[AGC017D] Game on Tree
Portal .
问题可以分解成若干棵子树,每棵子树都带着根节点,然后发现其 SG 值是子树的 SG 值加 1 1 1 ,直接处理即可。代码 。
[AGC010D] Decrementing
Portal .
如果初始 ∑ a i − 1 \sum a_i-1 ∑ a i − 1 为奇数,那么先手可以一直维持这个状态(只需要操作偶数即可,情况不会改变)。
初始为偶数呢?如果局面下只有一个奇数,那么操作它就可以出现偶公因数,模拟即可。代码 。
[AGC016F] Games on DAG
Portal .
不难想到按照 SG 值进行分层转移,对于新增加的 SG 值更小的部分,一定要有边连向它们中的点来保证 SG 值的大小。转移的时候直接枚举子集 S S S ,判断到达的 SG 值更小的集合 T T T ,此时令 SG ( T ) = k \operatorname{SG}(T)=k SG ( T ) = k ,设 f i f_i f i 代表考虑集合 i i i 中的点时 SG ( 1 ) = SG ( 2 ) \operatorname{SG}(1)=\operatorname{SG}(2) SG ( 1 ) = SG ( 2 ) 的方案数,转移:
对于 T → S T\rightarrow S T → S 的边,每一个 T T T 中的元素都至少向 S S S 中连一条边;
对于 S → T S\rightarrow T S → T 的边,随便连即可。
直接做即可。代码 。
[ABC278G] Generalized Subtraction Game
Portal .
如果可以先手第一步下在中间,然后我们就下模仿棋就行了。
否则,此时选择的区间长度固定,考虑计算 SG 函数,令 SG i \operatorname{SG}_i SG i 代表长度为 i i i 的游戏的 SG 值。
对于 i < l i<l i < l ,有 SG i = 0 \operatorname{SG}_i=0 SG i = 0 ,否则枚举选择的长度,有 SG i = mex j = 0 i − l { SG j xor SG i − j − l } \operatorname{SG}_i=\operatorname{mex}_{j=0}^{i-l}\{\operatorname{SG}_{j} \operatorname{xor} \operatorname{SG}_{i-j-l}\} SG i = mex j = 0 i − l { SG j xor SG i − j − l } 。
输出方案时采用 set
维护连续段,不断选择后手必败的区间即可。
[CF1458E] Nim Shortcuts
Portal .
正常情况下,黑色的是先手必败的:
但如果存在限制(黄色的也是必败态,那么情况会发生改变):
可以发现必败态是若干条斜线,初始斜线是 x = y x=y x = y ,特殊点会导致斜线向下和向右平移,发现这是个二维数点,扫描线维护使其向 x x x 轴方向平移的个数,树状数组维护 y y y 轴方向,用 x − y x-y x − y 的值判断是否在斜线上即可。代码 。
非公平组合
比较有趣。
[AGC048D] Pocky Game
Portal .
设 f l , r f_{l,r} f l , r 代表 a l a_l a l 至少为多少才能使得 [ l , r ] [l,r] [ l , r ] 先手必胜,g l , r g_{l,r} g l , r 代表 a r a_r a r 至少为多少才能使得 [ l , r ] [l,r] [ l , r ] 后手必胜。转移时由于最后是一个一个取,直接算即可,代码 。
[CF1033G] Chip Game
Portal .
模 a + b a+b a + b 意义下的局面是等价的,考虑枚举 a + b a+b a + b ,将 v v v 排序,计算出合法的值域 [ v i − 1 + 1 , v i ] [v_{i-1}+1,v_i] [ v i − 1 + 1 , v i ] ,而且应该减去存在两个 2 a ≤ v i 2a\le v_i 2 a ≤ v i 的情况,随便算算就好了。代码 。
题车