因为我太菜了,致使一些东西一学就忘,特开此文来记录下最让我头痛的数学相关问题。html
一些引用的文字都注释了原文连接,若侵犯了您的权益,敬请告知;若文章中出现错误,也烦请告知。算法
该文于 2018.3.31 完成最后一次修改(如有出错的地方,以后也会进行维护)。其主要内容限于数论和组合计数类数学相关问题。由于版面缘由,其他数学方面的总结会以全新的博文呈现。ubuntu
感谢你的造访。数组
因为该文完成的间隔跨度太大,不一样时期的内容的写法不严谨,甚至 $LaTeX$ 也有许多不规范的表达。我懒也不想改...请见谅...svg
$gcd(a, b) = gcd(b, a \mod b)$函数
证实:设 $c \mid a, c \mid b$ ,则 $c \mid (b-a)$ 。测试
设 $c \nmid a$ ,则 $c$ 不是 $a,b-a$ 的公因子。ui
设 $c \mid a$ , $c \nmid b$ ,则 $c$ 不是 $a,b-a$ 的公因子。 spa
1 int gcd(int a, int b) { 2 return b == 0 ? a : gcd(b, a%b); 3 }
对于一组不定方程 $a \times x+b \times y = c$ 。若 $gcd(a, b) \mid c$ 则这组方程有无数组解,不然无解。.net
求出一组 $a \times x+b \times y = gcd(a, b)$的解须要$exgcd$,是在$gcd$递归函数过程当中实现的。
设$x_0$,$y_0$是这一层的解,$x_1$,$y_1$是上一层的解。
首先边界条件:当$b = 0$时显然$x_0 = 1$,$y_0 = 0$。
其余状况下有:$x_0 = y_1$,$y_0 = x_1- \frac{a}{b} \times y_1$。
证实(摘自PIPIBoss):
$gcd(a, b) = x_0 \times a+y_0 \times b$$gcd(b, a \mod b) = x_1 \times b+y_1 \times (a \mod b) = x_1 \times b+y_1 \times (a-\frac{a}{b} \times b)$由于 $gcd(a, b) = gcd(b, a \mod b)$得 $x_0 \times a+y_0 \times b = x_1 \times b+y_1 \times (a-\frac{a}{b} \times b)$合并得 $x_0 \times a+y_0 \times b = y_1 \times a+(x_1-\frac{a}{b} \times y_1) \times b$根据恒等定理 $x_0 = y_1$,$y_0 = x_1-\frac{a}{b} \times y_1$
1 int exgcd(int a, int b, int &x, int &y) { 2 if (b == 0) { 3 x = 1; y = 0; 4 return a; 5 } 6 int c = exgcd(b, a%b, x, y); 7 int t = x; 8 x = y; 9 y = t-a/b*y; 10 return c; 11 }
对于正整数和
,若是有
,那么把这个同余方程中
的最小正整数解叫作
模
的逆元。
逆元通常用扩展欧几里得算法来求得,若是为素数,那么还能够根据费马小定理获得逆元为
。
推导过程以下:
另外,逆元还有线性算法:
首先,$1^{-1} ≡ 1(\mod p)$
而后,咱们设$p=k \times i+r$,$r<i$,$1<i<p$,再将这个式子放到$\mod p$意义下,就有:
$$k \times i+r ≡ 0(\mod p)$$
在等号两边同乘上$i^{-1}$,$r^{-1}$,就会获得:
$$k \times r^{-1}+i^{-1} ≡ 0(\mod p)$$
$$i^{-1} ≡ -k \times r^{-1}(\mod p)$$
$$i^{-1} ≡ -{\lfloor {p \over i} \rfloor} \times (p \mod i)^{-1}(\mod p)$$
递推代码就是:
1 A[i] = -(p/i)*A[p%i]
在《孙子算经》中有这样一个问题:“今有物不知其数,三三数之剩二(除以3余2),五五数之剩三(除以5余3),七七数之剩二(除以7余2),问物几何?”这个问题称为“孙子问题”,该问题的通常解法国际上称为“中国剩余定理”。具体解法分三步:
就这么简单。咱们在感叹神奇的同时不由想知道古人是如何想到这个方法的,有什么基本的数学依据吗?
咱们将“孙子问题”拆分红几个简单的小问题,从零开始,试图揣测古人是如何推导出这个解法的。
首先,咱们假设${n_1}$是知足除以3余2的一个数,好比2,5,8等等,也就是知足${3 \times k+2(k>=0)}$的一个任意数。一样,咱们假设${n_2}$是知足除以5余3的一个数,${n_3}$是知足除以7余2的一个数。
有了前面的假设,咱们先从${n_1}$这个角度出发,已知${n_1}$知足除以3余2,能不能使得${n_1+n_2}$的和仍然知足除以3余2?进而使得${n_1+n_2+n_3}$的和仍然知足除以3余2?
这就牵涉到一个最基本数学定理,若是有${ a \% b=c }$,则有${ (a+k \times b) \% b=c(k为非零整数) }$,换句话说,若是一个除法运算的余数为${c}$,那么被除数与${k}$倍的除数相加(或相减)的和(差)再与除数相除,余数不变。这个是很好证实的。
以此定理为依据,若是${n_2}$是3的倍数,${n_1+n_2}$就依然知足除以3余2。同理,若是${n_3}$也是3的倍数,那么${n_1+n_2+n_3}$的和就知足除以3余2。这是从${n_1}$的角度考虑的,再从${n_2}$,${n_3}$的角度出发,咱们可推导出如下三点:
所以,为使${n_1+n_2+n_3}$的和做为“孙子问题”的一个最终解,需知足:
因此,孙子问题解法的本质是从5和7的公倍数中找一个除以3余2的数${n_1}$,从3和7的公倍数中找一个除以5余3的数${n_2}$,从3和5的公倍数中找一个除以7余2的数${n_3}$,再将三个数相加获得解。在求${n_1}$,${n_2}$,${n_3}$时又用了一个小技巧,以${n_1}$为例,并不是从5和7的公倍数中直接找一个除以3余2的数,而是先找一个除以3余1的数,再乘以2。也就是先求出5和7的公倍数模3下的逆元,再用逆元去乘余数。
这里又有一个数学公式,若是${a \% b=c}$,那么${(a \times k) \% b=a \% b+a \% b+…+a \% b=c+c+…+c=k \times c(k>0)}$,也就是说,若是一个除法的余数为${c}$,那么被除数的${k}$倍与除数相除的余数为${k \times c}$。展开式中已证实。
最后,咱们还要清楚一点,${n_1+n_2+n_3}$只是问题的一个解,并非最小的解。如何获得最小解?咱们只须要从中最大限度的减掉掉3,5,7的公倍数105便可。道理就是前面讲过的定理“若是${a \%b=c}$,则有${(a-k \times b) \% b=c}$”。因此${(n_1+n_2+n_3)\% 105}$就是最终的最小解。
这样一来就获得了中国剩余定理的公式:
设正整数
两两互素,则同余方程组
有整数解。而且在模
下的解是惟一的,解为
其中
,而
为
模
的逆元。
1 int ex_gcd(int a, int b, int &x, int &y) { 2 if (b == 0) { 3 x = 1, y = 0; return a; 4 } 5 int gcd = ex_gcd(b, a%b, x, y); 6 int t = x; 7 x = y; 8 y = t-a/b*y; 9 return gcd; 10 } 11 int inv(int a, int b) { 12 int x, y; 13 ex_gcd(a, b, x, y); 14 return (x%b+b)%b; 15 } 16 int CRT() { 17 int M = 1, ans = 0; 18 for (int i = 1; i <= n; i++) M *= m[i]; 19 for (int i = 1; i <= n; i++) 20 (ans += a[i]*(M/m[i])*inv(M/m[i], m[i])) %= M; 21 return (ans+M)%M; 22 }
普通的中国剩余定理要求全部的互素,那么若是不互素呢,怎么求解同余方程组?
这种状况就采用两两合并的思想,假设要合并以下两个方程:
那么获得:
咱们须要求出一个最小的${x}$使它知足:
那么${x_1}$和${x_2}$就要尽量的小,因而咱们用扩展欧几里得算法求出${x_1}$的最小正整数解,将它代回${a_1+m_1x_1}$,获得${x}$的一个特解${x'}$,固然也是最小正整数解。
因此${x}$的通解必定是${x'}$加上${lcm(m1,m2) \times k}$,这样才能保证${x}$模${m_1}$和${m_2}$的余数是${a_1}$和${a_2}$。由此,咱们把这个${x'}$当作新的方程的余数,把${lcm(m1,m2)}$当作新的方程的模数。(这一段是关键)
合并完成:
首先咱们来看一个问题:
在一个平面直角坐标系中,只能往右或往上走一个单位长度,问有多少种不一样的路径能够从左下角 走到右上角
,而且要求路径不能通过直线
上方的点,下图中的路径都是合法的(图片来源 Wikipedia)
若是没有限制条件,那么从左下角走到右上角一共有 步,有
步是往右,另外
步是往上,那么路径方案数就是
步中选择
步往右,一共有
(即
)种方案
那么咱们考虑一下这里面有多少种方案是不合法的
首先对于每一种不合法的方案,它的路径必定与 有交。咱们找到它与
的第一个交点,而后将这个点后面部分的路径关于
作一个对称。因为原来路径到达
,新的对称以后的路径就会到达
。这样咱们把每一种不合法方案都对应到了一条从
到
的路径,如今再来看是否每一条这样的路径都能对应到一种不合法方案,若是是,那么这就创建了一个一一映射的关系,也就是它们的方案总数相同。这是确定的,由于每一条这样的路径一定与
有交,那么对称回去,就获得一条不合法方案
因为从 到
的路径有
条,那么合法的方案就是
咱们把这个方案数记为 ,这就是著名的 Catalan 数
咱们来看看它的前几项( 从
开始)
1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190
再来看一个问题:有多少种不一样的长度为 的括号序列?
首先一个括号序列是指 (), ()(), (())() 这样的由括号组成的序列,而且没有左右括号没法匹配的状况
咱们能够将长度为 的括号序列映射成刚刚所说的路径:首先对于左括号,那么就向右走一个单位长度,对于右括号,那么就向上走一个单位长度,因为括号序列合法,那么每次向右走的次数不会少于向上的次数,也就是这条路径不会在
之上。再考虑每一条这样的路径,也可以对应到一种合法的括号序列,所以,长度为
的括号序列的方案数就是
如今来考虑你有 个元素(元素之间是没有区别的)和一个栈,每次能够将一个元素入栈,或者将栈顶元素弹出,问有多少种可能的操做序列,这能够将问题对应成括号序列,入栈为左括号,出栈为右括号,所以方案数也是
如今有 我的,他们身高互不相同,他们要成两排,每一排有
我的,而且知足每一排必须是从矮到高,且后一排的人要比前一排对应的人要高,问有多少种排法
咱们考虑先把这些人从矮到高排成一排,那么如今来分配哪一个人在前,哪一个人在后,例若有 我的,身高是 1, 2, 3, 4, 5, 6
那么咱们用 1 表示这我的应该在后排,0 表示这我的应该在前排,例如说 100110 表示两排分别是 2, 3, 6 和 1, 4, 5 这是不合法的
那么合法方案应该是怎么样的呢?后排要比前排对应的人高,也就是说 0 的出现次数在每个地方都不该该小于 1,这偏偏又是一个括号序列,所以,方案仍然是 Catalan 数
如今你须要统计有多少种不一样的 个结点的二叉树
图上的是 个结点的二叉树,一共有
种方案
朴素的想法是因为二叉树是递归定义的,能够考虑使用递推方法
咱们能够用 表示有
个结点的二叉树的方案数(空树算一种,即
),那么枚举子树大小能够获得方程
若是直接计算,你须要 的时间
如今咱们换一个角度来想,对这棵二叉树进行遍历,而且考虑一个括号序列,当第一次遇到这个结点的时候,在括号序列末尾添加一个左括号,在从左子树回到这个结点的时候,在括号序列中添加一个右括号,这样,将每一种不一样的二叉树都对应到了一种不一样的括号序列,一样对于每一种不一样的括号序列均可以找到对应的一种不一样的二叉树,所以,有 个结点的二叉树的数量也是
咱们能够定义序列 的生成函数为
,再根据上面的递推式,能够列出方程
解方程能够获得
由于 ,所以对上式求极限
所以取负号,
根据广义二项式定理展开
而后考虑第 项系数
所以能够获得
一样获得
对任一整数 $a > 1$ ,有 $a={p_1}^{a_1}{p_2}^{a_2}…{p_n}^{a_n}$ ,其中 $p_1<p_2<…<p_n$ 均为素数,而 $a_1$,$a_2$…,$a_n$ 是正整数。
对于惟一分解定理中的式子,知足 $a$ 的正约数个数为: $(1+a_1)(1+a_2)…(1+a_n)$
$a$ 的约数和个数为: $\prod_{i = 1}^n \sum_{j = 0}^{a_i} p_i^j$
若 $p$ 是素数,则 $(p-1)! \equiv -1 \pmod{p}$ 。
其逆定理也成立,即:若对某一正整数 $p$ ,有 $(p-1)! \equiv -1 \pmod{p}$ ,则 $p$ 必定是素数。
因为 $p \mid (p-1)!+1$ ,能够构造函数 $f(n) = \sin(\pi \cdot \frac{(n-1)!+1}{n})$ 。这个函数的零点都是素数,而且全部素数都是这个函数的零点。
若 $p$ 为素数, $a$ 为正整数,且 $a$ 和 $p$ 互素,则: $a^{p-1} \equiv 1 \pmod{p}$ 。
证实:首先, $p-1$ 个整数 $a,2a,3a,\cdots,(p-1)a$ 中没有一个是 $p$ 的倍数。
其次, $a,2a,3a,\cdots,(p-1)a$ 中没有任何两个同余于模 $p$ 的。
因而: $a,2a,3a,\cdots,(p-1)a$ 对模 $p$ 的同余既不为 $0$ ,也没有两个同余相同,所以,这 $p-1$ 个数对模 $p$ 的同余必定是 $1,2,3,\cdots,p-1$ 的某一种排列,即:$$a \cdot 2a \cdot 3a \cdot \cdots \cdot (p-1)a \equiv 1 \cdot 2 \cdot 3 \cdot \cdots \cdot (p-1) \pmod{p}$$
化简为: $$a^{p-1} \cdot (p-1)! \equiv (p-1)! \pmod{p}$$
因为模数 $p$ 是质数,根据威尔逊定理得出 $(p-1)!$ 和 $p$ 互质。因此约去 $(p-1)!$ 。
获得: $$a^{p-1} \equiv 1 \pmod{p}$$
欧拉函数:记小于等于 $n$ 的数中与 $n$ 互质的数的个数为 $\varphi(n)$ 。
引理1:
①若是 $n$ 为某一个素数 $p$ ,则 $\varphi(p) = p-1$;
②若是 $n$ 为某一个素数 $p$ 的幂次 $p^a$ ,则 $\varphi(p^a) = (p-1) \cdot p^{a-1}$ ;
③若是 $n$ 为两个互质的数 $a,b$ 的乘积,则 $\varphi(ab) = \varphi(a) \cdot \varphi(b)$ 。
证实:①显然;
②由于比 $p^a$ 小的数有 $p^a-1$ 个,那么有 $p^{a-1}-1$ 个数能被 $p$ 所整除(由于把 $1 \sim p^a-1$ 的 $p$ 的倍数都筛去了),因此 $\varphi(p^a) = (p-1) \cdot p^{a-1}$ ;
③对于全部小于 $a$ 且与 $a$ 互质的数 $p$ 和小于 $b$ 且与 $b$ 互质的数 $q$,都能组成 $aq+bp$ 与 $n$ 互质,所以由乘法原理,知足条件。
引理2:
设 $n = \prod_{i = 1}^k p_i^{a_i}$ 为正整数 $n$ 的素数幂乘积表示式。则 $$\varphi(n) = n \cdot \prod_{i = 1}^k \left(1-\frac{1}{p_i} \right)$$
证实:
\begin{aligned} \varphi(n) &= \prod_{i = 1}^k \varphi(p_i^{a_i})\\&= \prod_{i = 1}^k p_i^{a_i}\cdot \left(1-\frac{1}{p_i} \right)\\&= n \cdot \prod_{i = 1}^k \left(1-\frac{1}{p_i} \right)\end{aligned}
欧拉定理:若 $a$ 与 $m$ 互质,则 $a^{\varphi(m)} \equiv 1 \pmod{m}$ 。
证实:
按照证实费马小定理思路:
将小于 $m$ 的 $\varphi(m)$ 个与 $m$ 互质的整数取出,为 $x_1,x_2,\cdots,x_{\varphi(m)}$ 。
取出 $\varphi(m)$ 个整数 $x_1a,x_2a,\cdots,x_{\varphi(m)}a$ ,其中没有一个是 $m$ 的倍数,也没有两个模 $m$ 同余的。
简要证实:假设 $x_ia \equiv x_ja \pmod m$ (假设 $x_i > x_j$ )。显然 $(x_i-x_j)a \equiv 0 \pmod m$ ,即 $m \mid (x_i-x_j)a$ ,因为 $gcd(a, m) = 1$ 且 $(x_i-x_j) < m$ ,则 $m \nmid (x_i-x_j)a$ ,矛盾,原命题成立。
又由于 $x_1a,x_2a,\cdots,x_{\varphi(m)}a$ 在模 $m$ 意义下均与 $m$ 互素。
简要证实:记 $x_ia \equiv b \pmod{m}$ ,假设 $b$ 不互素,显然 $gcd(b, m) = d \neq 1$ , $b = k_1 \cdot d, m = k_2 \cdot d$ ,因为 $x_ia = b+K'm$ ,即 $x_ia = (k_1+K'k_2) \cdot d$ ,则 $x_ia$ 与 $m$ 有共同因子 $d$ ,但因为 $a, x_i$ 均与 $m$ 互素,矛盾,原命题成立。
有上述两个定理,故 $x_1a,x_2a,\cdots,x_{\varphi(m)}a$ 在模 $m$ 意义下是 $x_1,x_2,\cdots,x_{\varphi(m)}$ 的一个排列。
故有: $$x_1a\cdot x_2a\cdot\cdots\cdot x_{\varphi(m)}a \equiv x_1\cdot x_2\cdot\cdots\cdot x_{\varphi(m)} \pmod{m}$$
化简为: $$a^{\varphi(m)}\cdot x_1\cdot x_2\cdot\cdots\cdot x_{\varphi(m)} \equiv x_1\cdot x_2\cdot\cdot\cdot x_{\varphi(m)} \pmod{m}$$
因为 $x_1,x_2,\cdots,x_{\varphi(m)}$ 均与 $m$ 互质,因此能够约去,得: $$a^{\varphi(m)} \equiv 1 \pmod{m}$$
线性筛欧拉函数
用到的性质(其中 $p$ 为素数):
① $\varphi(p) = p-1$ ;
②若是 $p \mid i$ ,那么 $\varphi(i \cdot p) = p\cdot \varphi(i)$ ;
③若是 $p \nmid i$ ,那么 $\varphi(i \cdot p) = (p-1)\cdot \varphi(i)$ 。
证实:①显然;
②因为 $p \mid i$ ,显然 $i$ 与 $i \cdot p$ 间没有不一样的因子。
则对于一个整数 $x$ ,若 $gcd(x,i) = 1$ 则 $gcd(x,i \cdot p) = 1$ 。
咱们将从 $0$ 开始长度为 $i \cdot p$ 的数轴分红 $p$ 段长度为 $i$ 的小段。对于第一段为 $[1,i]$ ,第二段为 $[i+1, i+i]$ ……以此类推。
对于第一段中,与 $i$ 互质的数有 $\varphi(i)$ 个。即在第一段中与 $i \cdot p$ 互质的数也有 $\varphi(i)$ 个。
如今咱们证实对于整数 $x$ 若与 $i$ 互质,则 $x+i$ 也与 $i$ 互质。
采用反证法,咱们假设 $gcd(x, i) = 1$ 但 $gcd(x+i, i) = b \neq 1$ 。
容易发现: \begin{cases} \begin{aligned} x+i = b\cdot k_1 \\ i = b \cdot k_2 \end{aligned} \end{cases} $k_1,k_2$ 均为整数。
因此 $x = (k_1-k_2)\cdot b$ ,故 $gcd(x, i) = b \neq 1$ ,与题设不符,原命题成立。
下证对于整数 $x$ 若与 $i$ 不互质,则 $x+i$ 也与 $i$ 不互质。
假设 $gcd(x, i) = b \neq 1$ , \begin{cases} \begin{aligned} x = b\cdot k_1 \\ i = b \cdot k_2 \end{aligned} \end{cases}$k_1,k_2$ 均为整数。
因此 $x+i = (k_1+k_2)\cdot b$ ,故 $gcd(x+i, i) = b \neq 1$ ,原命题成立。
综上,若是 $p \mid i$ ,那么 $\varphi(i \cdot p) = p\cdot \varphi(i)$ ;③因为 $p \nmid i$ ,且 $p$ 为质数,因此 $i$ 与 $p$ 互质,由于欧拉函数是积性函数, $\varphi(i \cdot p) = \varphi(p)\cdot \varphi(i)$ ,又 $\varphi(p) = p-1$ 。
1 void get_phi() { 2 memset(isprime, 1, sizeof(isprime)); isprime[1] = 0; phi[1] = 1; 3 for (int i = 2; i <= n; i++) { 4 if (isprime[i]) phi[i] = i-1, prime[++tot] = i; 5 for (int j = 1; j <= tot && i*prime[j] <= n; j++) { 6 isprime[i*prime[j]] = 0; 7 if (!(i%prime[j])) {phi[i*prime[j]] = phi[i]*prime[j]; break; } 8 else phi[i*prime[j]] = phi[prime[j]]*phi[i]; 9 } 10 } 11 }
扩展欧拉定理:$a^q \equiv a^{q\ mod\ \varphi(m)+\varphi(m)} \pmod{m}$ ,其中 $a,m \in \mathbb{Z}^*$
要证实扩展欧拉定理则只需证a的任意一个质因子
,
简单解释一下这是如何转化的。
根据同余式可乘可推公式二出
即
根据同余式可乘获得
能够发现这就是
那么如今要证实的东西已经转化, 考虑如何证得。
为
某质因子, 若
则由欧拉定理显然证得, 考虑
则
(由于
和
互质, 由欧拉定理可得)
由欧拉函数的积性
因此
从而
显然式子同时乘以
获得
由于
显然
因此两边同时乘以
能够获得上面转化出来要求的式子
证毕。
$$a^b\equiv
\begin{cases}
a^{b\ mod \ \varphi(p)}~~~~~~~~~~~gcd(a,p)=1\\
a^b~~~~~~~~~~~~~~~~~~~~~gcd(a,p)\neq1,b<\varphi(p)\\
a^{b\ mod \ \varphi(p)+\varphi(p)}~~~~gcd(a,p)\neq1,b\geq\varphi(p)
\end{cases}\pmod{p}$$
主要利用费马小定理 $a^{p-1} \equiv 1 \pmod{p}$ ,实现的过程以下:
而在实际运用中,咱们能够直接取 $r = 0$ ,从而省去步骤 $3$ 的测试,提升速度;另外的能够首先用几个小素数对 $N$ 进行测试。除此以外也能够引入“二次探测”的思想,防止被 Carmichael数 卡。
二次探测:对于一个奇素数 $p$ ,对于关于 $x$ 的同余方程 $x^2 \equiv 1 \pmod{p}$ ,在 $[1, p)$ 上的解仅有 $x = 1$ 及 $x = p-1$ 。
1 const int prime[10] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29}; 2 3 LL quick_multi(LL a, LL b, LL p) { 4 LL ans = 0; 5 while (b) { 6 if (b&1) ans = (ans+a)%p; 7 a = (a+a)%p, b >>= 1; 8 } 9 return ans; 10 } 11 LL quick_pow(LL a, LL b, LL p) { 12 LL ans = 1; 13 while (b) { 14 if (b&1) ans = quick_multi(ans, a, p); 15 a = quick_multi(a, a, p), b >>= 1; 16 } 17 return ans; 18 } 19 bool Miller_Rabin(LL x) { 20 if (x == 1) return false; 21 for (int i = 0; i < 10; i++) { 22 if (x == prime[i]) return true; 23 if (!(x%prime[i])) return false; 24 } 25 LL m = x-1, k = 0; 26 while (!(m&1)) m >>= 1, ++k; 27 for (int i = 0; i < 10; i++) { 28 LL a = rand()%(x-2)+2, pre = quick_pow(a, m, x), y; 29 for (int j = 0; j < k; j++) { 30 y = quick_multi(pre, pre, x); 31 if (y == 1 && pre != 1 && pre != x-1) return false; 32 pre = y; 33 } 34 if (pre != 1) return false; 35 } 36 return true; 37 }
代码为求一个大数的最小质因数(POJ 1811):
1 LL Pollard_Rho(LL x, int c) { 2 LL i = 1, k = 2, a1, a2; 3 a1 = a2 = rand()%(x-1)+1; 4 while (true) { 5 ++i, a1 = (quick_multi(a1, a1, x)+c)%x; 6 LL d = gcd(Abs(a1-a2), x); 7 if (1 < d && d < x) return d; 8 if (a1 == a2) return x; 9 if (i == k) a2 = a1, k <<= 1; 10 } 11 } 12 void find(LL x, int c) { 13 if (x == 1) return; 14 if (Miller_Rabin(x)) {ans = Min(ans, x); return; } 15 LL p = x, k = c; 16 while (p == x) p = Pollard_Rho(x, c--); 17 find(p, k), find(x/p, k); 18 }
1 LL BSGS(LL a, LL b, LL c) { 2 if (b == 1) return 0; 3 if (a == 0 && b != 0) return -1; 4 mp.clear(); 5 LL tim = ceil(sqrt((double)c)), tmp = b%c; 6 for (int i = 0; i <= tim; i++) { 7 mp.insert(tmp, i); tmp = tmp*a%c; 8 } 9 LL t = tmp = quick_pow(a, tim, c); 10 for (int i = 1; i <= tim; i++) { 11 if (mp.count(tmp)) return tim*i-mp.query(tmp); 12 tmp = tmp*t%c; 13 } 14 return -1; 15 }
扩展BSGS:
当模数 $c$ 不是质数的时候,显然不能直接使用 $BSGS$ 了,考虑它的扩展算法。
前提:同余性质。
令 $d = gcd(A, C)$ , $A = a \cdot d,B = b \cdot d, C = c \cdot d$
则 $a \cdot d \equiv b \cdot d \pmod{c \cdot d}$
等价于 $a \equiv b \pmod{c}$
所以咱们能够先消除因子。
对于如今的问题 $(a \cdot d)^x \equiv b \cdot d \pmod{c \cdot d}$ 当咱们提出 $d = gcd(A, C)$ ($d \neq 1$)后,原式化为 $a \cdot (a \cdot d)^{x-1} \equiv b \pmod{c}$ 。
即求 $D \cdot A^{x-cnt} \equiv b \pmod{c}$ ,令 $x = i \cdot r-j+cnt$ , $r$ 是块大小, $i,j\in \mathbb{Z}$ 。以后的作法就和 $BSGS$ 同样了。
值得注意的是由于这样求出来的解 $x \geq cnt$ 的,但有可能存在解 $x < cnt$ ,因此一开始须要特判。
1 LL exBSGS(LL a, LL b, LL c) { 2 if (b == 1) return 0; 3 if (a == 0 && b != 0) return -1; 4 LL cnt = 0, d = 1, t; 5 while ((t = gcd(a, c)) != 1) { 6 if (b%t) return -1; 7 ++cnt, b /= t, c /= t, d = d*(a/t)%c; 8 if (d == b) return cnt; 9 } 10 mp.clear(); 11 LL tim = ceil(sqrt(c)), tmp = b%c; 12 for (int i = 0; i <= tim; i++) { 13 mp.insert(tmp, i); tmp = tmp*a%c; 14 } 15 t = tmp = quick_pow(a, tim, c); tmp = (tmp*d)%c; 16 for (int i = 1; i <= tim; i++) { 17 if (mp.count(tmp)) return tim*i-mp.query(tmp)+cnt; 18 tmp = tmp*t%c; 19 } 20 return -1; 21 }
无重复的排列 $A_n^m = \frac{n!}{(n-m)!}$
无重复的组合 $C_n^m = \frac{A_n^m}{A_m^m} = \frac{n!}{m!(n-m)!}$
可重复的排列 $n^m$
可重复的组合 $C_{n+m-1}^m$
证实:用 $1,2,3,\cdots,n$ 表示 $n$ 个不一样元素,这时从这 $n$ 个不一样元素中取 $m$ 个元素的可重复组合具备下列形式: $$\{i_1,i_2,\cdots,i_m \},(1 \leq i_1 \leq i_2 \leq \cdots \leq i_m \leq n)$$
在上述每一个数从左至右逐个分别加上: $0,1,\cdots,m-1$ ,获得 $\{j_1,j_2,\cdots,j_m \}$ ,其中 $j_1 = i_1, j_2 = i_2+1,\cdots ,j_m = i_m+(m-1)$ ,知足 $1 \leq j_1 < j_2 < \cdots < j_m \leq n+m-1$ ,而 $\{j_1,j_2,\cdots,j_m \}$ 刚好是从 $1,2,\cdots,n+m-1$ 这 $n+m-1$ 个元素中取 $m$ 个不一样元素。
不全相异元素的全排列 若是 $n$ 个元素中,分别有 $n_1,n_2,\cdots,n_k$ 个元素相同,且 $n_1+n_2+\cdots+n_k = n$ ,则这 $n$ 个元素的全排列称为不全相异元素的全排列,其不一样的排列个数记为 $\binom{n}{n_1~~n_2~~\cdots~~n_k}$ ,则 $\binom{n}{n_1~~n_2~~\cdots~~n_k} = \frac{n!}{n_1!n_2!\cdots n_k!}$ 。
证实:假设知足条件的排列数为 $f$ ,显然 $f\cdot n_1! \cdot n_2! \cdot \cdots \cdot n_k! = n!$ 。故 $f = \frac{n!}{n_1!n_2!\cdots n_k!} = \binom{n}{n_1~~n_2~~\cdots~~n_k}$ 。
多组组合 把 $n$ 个元素分为 $k(k \leq n)$ 个按照必定顺序排列的组,其中第 $i$ 组有 $n_i$ 个元素($i = 1,2,\cdots,k$ , $n_1+n_2+\cdots+n_k = n$),则不一样的分组方法的种数为 $\binom{n}{n_1~~n_2~~\cdots~~n_k} = \frac{n!}{n_1!n_2!\cdots n_k!}$ 。
证实:
\begin{aligned}
&~~~~C_n^{n_1}\cdot C_{n-n_1}^{n_2}\cdot \cdots \cdot C_{n-n_1-n_2-\cdots-n_{k-1}}^{n_k}\\ &= \frac{n!}{n_1!\cdot(n-n_1)!}\cdot \frac{(n-n_1)!}{n_2!\cdot(n-n_1-n_2)!}\cdot \cdots \cdot \frac{(n-n_1-\cdots -n_{k-1})!}{n_k!\cdot(n-n_1-\cdots -n_{k-1}-n_k)!}\\&=\frac{n!}{n_1!n_2!\cdots n_k!}
\end{aligned}
圆排列 将 $n$ 个不一样元素不分首尾排成一圈,称为 $n$ 个相异元素的圆排列,其排列种数为 $(n-1)!$ 。
项链数 将 $n$ 粒不一样的珠子用线串成一副项链,则获得的不一样项链数为 \begin{cases} 1& \text{$n \in \{1,2\}$}\\ \frac{1}{2}\cdot(n-1)!& \text{$n \in [3,+\infty)$} \end{cases}
一类不定方程的非负整数解的个数 不定方程 $x_1+x_2+\cdots+x_m = n~(m,n \in \mathbb{N}_+)$ 的非负整数解的个数为 $C_{n+m-1}^{m-1}$ 。推论:上述不定方程的正整数解的个数为 $C_{n-1}^{m-1}$ 。
证实:都可用“隔板法”证实,推论还需用“垫球法”。
容斥原理 设 $A_1,A_2,\cdots,A_n$ 为有限集合,用 $|A_i|$ 表示集合 $A_i$ 中的元素个数,那么
$$|A_1 \cup A_2 \cup \cdots \cup A_n| = \sum_{i=1}^n |A_i|-\sum_{1\leq i< j\leq n} |A_i\cap A_j|+\sum_{1\leq i< j< k\leq n} |A_i\cap A_j \cap A_k|-\cdots +(-1)^{n-1} |A_1\cap A_2 \cdots \cap A_n|$$
证实:若 $a \in A_1 \cup A_2 \cup \cdots \cup A_n$ ,则 $a$ 至少属于 $A_1,A_2,\cdots,A_n$ 中一个集合。不妨设 $a$ 属于 $A_1,A_2,\cdots,A_k~(1\leq k\leq n)$ 而不属于其余集合。因而 $a$ 在上式左端计算了一次。而 $a$ 在右端共计算的次数为
\begin{aligned} &~~~~C_k^1-C_k^2+C_k^3-\cdots+(-1)^{k-1}C_k^k\\ &= C_k^0-(C_k^0-C_k^1+\cdots+(-1)^kC_k^k)\\ &= 1-(1-1)^k \\ &= 1 \end{aligned}若 $a \notin A_1 \cup A_2 \cup \cdots \cup A_n$ ,则 $a$ 在上式左右两端计算的次数都为 $0$ 。原式成立。
筛法公式 设 $S$ 是有限集合, $A_i \subset S~(i=1,2,\cdots,n)$ , $A_i$ 在 $S$ 中的补集为 $\complement_S A_i~(i=1,2,\cdots,n)$ 则
$$|\complement_SA_1\cap\complement_SA_2\cap\cdots\cap\complement_SA_n| = |S|-\sum_{i=1}^n |A_i|+\sum_{1\leq i< j\leq n} |A_i\cap A_j|-\sum_{1\leq i< j< k\leq n} |A_i\cap A_j \cap A_k|+\cdots +(-1)^n |A_1\cap A_2 \cdots \cap A_n|$$
证实:由于 $|A_1 \cup A_2 \cup \cdots \cup A_n|=|S|-|\complement_S(A_1 \cup A_2 \cup \cdots \cup A_n)|$ ,而且由德·摩根律,咱们有 $\complement_S(A_1 \cup A_2 \cup \cdots \cup A_n)=\complement_SA_1\cap\complement_SA_2\cap\cdots\cap\complement_SA_n$ 。再加上容斥原理的式子,得证。
错排公式 $D_n = n!\left(1-\frac{1}{1!}+\frac{1}{2!}-\frac{1}{3!}+\cdots+(-1)^n\frac{1}{n!}\right)$
置换及其不动点 给定集合 $X=\{1,2,\cdots,n\}$ , $\varphi$ 是从 $X$ 到 $X$ 上的一一映射,一般记为
$$\varphi = \left\{^{~~~~1~~~~~~2~~~~~~\cdots~~~~~~n~~~~}_{\varphi(1)~~\varphi(2)~~~~\cdots~~~~\varphi(n)}\right\}$$
则称 $\varphi$ 是 $X$ 上的置换,其中 $\varphi(i)$ 是元素 $i$ 在映射 $\varphi$ 下的象。由于是一一映射,因此 $\varphi(1),\varphi(2),\cdots,\varphi(n)$ 其实是 $1,2,\cdots,n$ 的一个排列。知足 $\varphi(i) = i$ 的数 $i$ 称为 $\varphi$ 的一个不动点。容易证实,集合 $X$ 上没有任何不动点的置换 $\varphi$ 的个数是 $D_n = n!\left(1-\frac{1}{1!}+\frac{1}{2!}-\frac{1}{3!}+\cdots+(-1)^n\frac{1}{n!}\right)$ 。
第一抽屉原理 若是将 $m$ 个物品放入 $n$ 个抽屉内,那么必有一个抽屉内至少有 $\left\lfloor \frac{m-1}{n}\right\rfloor+1$ 个物品。
第二抽屉原理 若是将 $m$ 个物品放入 $n$ 个抽屉内,那么必有一个抽屉内至多有 $\left\lfloor \frac{m}{n}\right\rfloor$ 个物品。
设 $f(x) = (1+x)^n$ ,由二项式定理,有 $$f(x) = \sum_{k=0}^n C_n^kx^k=C_n^0+C_n^1x+C_n^2x^2+\cdots+C_n^nx^n$$
这时, $f(x)$ 对应了一个数列 $\{C_n^k,0\leq k\leq n\}$ ,即生成数列 $\{C_n^k\}$ ,所以,咱们把函数 $f(x) = (1+x)^n$ 称为数列 $\{C_n^k\}$ 的生成函数或母函数。
通常地说,对于有穷数列 $$a_0,a_1,a_2,\cdots,a_n$$
多项式 $f(x) = \sum_{k=0}^n a_kx^k=a_0+a_1x+a_2x^2+\cdots+a_nx^n$ 称为数列 $\{a_k\}$ 的母函数。
更通常地,对于无穷数列 $$a_0,a_1,\cdots,a_n,\cdots$$
咱们称下列形式幂级数 $$f(x) = \sum_{n=0}^\infty a_nx^n=a_0+a_1x+\cdots+a_nx^n+\cdots$$
为无穷数列 $\{a_n\}$ 的母函数。
关于形式幂级数咱们做以下的规定:设 $f(x) = \sum_{n=0}^\infty a_nx^n$ , $g(x) = \sum_{n=0}^\infty b_nx^n$ 是两个形式幂级数,咱们规定
(1) $f(x)=g(x)$ ,当且仅当 $a_n=b_n~(n=0,1,2,\cdots)$ ;
(2) $f(x) \pm g(x) = \sum_{n=0}^\infty(a_n\pm b_n)x^n$ ;
(3) $\alpha f(x) = \sum_{n=0}^\infty(\alpha a_n)x^n$ , $\alpha$ 为常数;
(4) $f(x)g(x) = \sum_{n=0}^\infty c_nx^n$ ,其中 $c_n = \sum_{k=0}^na_kb_{n-k},n=0,1,2,\cdots$ 。
公式一(无穷递缩等比数列求和公式) $$\frac{1}{1-x}=\sum_{n=0}^\infty x^n=1+x+x^2+\cdots+x^n+\cdots(|x|<1)$$
公式二 $$(1-x)^{-k}=\sum_{n=0}^\infty C_{n+k-1}^{k-1}x^n=1+C_{k}^{k-1}x+C_{k+1}^{k-1}x^2+\cdots+C_{n+k-1}^{k-1}x^n+\cdots(k \in \mathbb{Z}^*,|x|<1)$$
证实:公式二可由公式一两边求 $k-1$ 阶导数后除以 $(k-1)!$ 而获得。
莫比乌斯函数,是一个积性函数,记做 $\mu$ ,它的定义以下:
(1)若 $d = 1$ ,那么 $\mu(d)=1$
(2)若 $d=p_1p_2\cdots p_k$ , $p_i$ 均为互异素数,那么 $\mu(d)=(-1)^k$
(3)其余状况下 $\mu(d)=0$
性质:对于 $\forall n \in \mathbb{N}_+$
$$\sum_{d\mid n} \mu(d)=\begin{cases} 1 &n=1\\0 &n>1\end{cases}$$
证实:1. $n=1$ 时显然成立;
2. $n>1$ 时,将 $n$ 分解为 $p_1^{a_1}p_2^{a_2}\cdots p_k^{a_k}$ , $\mu(d)\neq 0$ 的只有次数均为 $1$ 的因子,其中质因数个数为 $i$ 的因子个数有 $C_k^i$ 个。
那么就有 \begin{aligned}\sum_{d\mid n} \mu(d)&=C_k^0-C_k^1+\cdots+(-1)^kC_k^k\\&=(1-1)^k=0 \end{aligned}
线性筛莫比乌斯函数
1 void get_mu() { 2 memset(isprime, 1, sizeof(isprime)); isprime[1] = 0, mu[1] = 1; 3 for (int i = 2; i <= N; i++) { 4 if (isprime[i]) prime[++tot] = i, mu[i] = -1; 5 for (int j = 1; j <= tot && i*prime[j] <= N; j++) { 6 isprime[i*prime[j]] = 0; 7 if (!(i%prime[j])) {mu[i*prime[j]] = 0; break; } 8 else mu[i*prime[j]] = -mu[i]; 9 } 10 } 11 }
若 $F(n)$ 和 $f(n)$ 是定义在非负整数集合上的两个函数,而且知足条件 $F(n)=\sum_{d\mid n} f(d)$ 。那么咱们获得结论: $$f(n)=\sum_{d\mid n} \mu(d)F(\frac{n}{d})$$
证实: $$\sum_{d|n}\mu(d)F(\frac{n}{d})=\sum_{d|n}\mu(d)\sum_{k|\frac{n}{d}}f(k)=\sum_{k|n}f(k)\sum_{d|\frac{n}{k}}\mu(d)=f(n)$$
由这个定理咱们能够获得莫比乌斯函数的另一个性质: 对于$\forall n \in \mathbb{N}_+$
$$\sum_{d\mid n} \frac{\mu(d)}{d}=\frac{\varphi(n)}{n}$$
证实:
引理: $n=\sum_{d\mid n} \varphi(d)$
证实:
对于 $n$ 的每一个因数 $d$ ,咱们取出 $[1,d]$ 内的 $\varphi(d)$ 个与 $n$ 互素的数记作集合 $A=\{a_1,a_2,\cdots,a_{\varphi(d)}\}$ ,将集合 $A$ 内的元素对应到集合 $B=\{a_1\frac{n}{d},a_2\frac{n}{d},\cdots,a_{\varphi(d)}\frac{n}{d}\}$ 。显然 $gcd(a_i\frac{n}{d},n)=\frac{n}{d}$ 。因为 $d$ 枚举了全部 $n$ 的因数,因此 $\frac{n}{d}$ 也是。则集合 $B$ 内是 $[1,n]$ 内全部的数。故原命题成立。
有了这个引理,咱们将莫比乌斯反演定理中的 $F(n) = n,f(n) = \varphi(n)$ 。 \begin{aligned}\varphi(n)&=\sum_{d\mid n} \frac{n}{d}\mu(d)\\ \frac{\varphi(n)}{n}&=\sum_{d\mid n} \frac{\mu(d)}{d} \end{aligned}
第二形式: $$F(n)=\sum_{n\mid d} f(d)\Rightarrow f(n)=\sum_{n\mid d} \mu(\frac{d}{n})F(d)$$
证实:令 $k=\frac{d}{n}$ ,那么 $$\sum^{+\infty}_{k=1}\mu(k)F(nk)=\sum^{+\infty}_{k=1}\mu(k)\sum_{nk|t}f(t)=\sum_{n|t}f(t)\sum_{k|\frac{t}{n}}\mu(k)=f(n)$$
若 $f(n)$ 是一个积性函数,求 $f(n)$ 的前缀 $S(n)$ 。即 $S(n)=\sum\limits_{i=1}^nf(n)$ 。
狄利克雷卷积
对于数论函数 $g(n),f(n)$ ,其狄利克雷卷积 $h(n)$ 也是一个数论函数 $$h(n)=\sum_{d\mid n}g(d)f\left(\frac{n}{d}\right)$$
咱们找到另外一个积性函数 $g(n)$ ,让 $f(n)$ 和 $g(n)$ 作一个卷积 $$(g*f)(n)=\sum_{d\mid n}g(d)f\left(\frac{n}{d}\right)$$
求卷积的前缀 $$\sum_{i=1}^n(g*f)(i)=\sum_{i=1}^n\sum_{d|i}g(d)f\left(\frac{i}{d}\right)$$
提出右式的 $d$ \begin{aligned}\Rightarrow\sum_{i=1}^n(g*f)(i)&=\sum_{d=1}^{n}g(d)\sum_{d|i}f\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}
容易获得这个式子 $$g(1)S(n)=\sum_{i=1}^ng(i)S\left(\left\lfloor\frac{n}{i}\right\rfloor\right)-\sum_{i=2}^ng(i)S\left(\left\lfloor\frac{n}{i}\right\rfloor\right)$$
其实就是 $$g(1)S(n)=\sum_{i=1}^n(g*f)(i)-\sum_{i=2}^ng(i)S\left(\left\lfloor\frac{n}{i}\right\rfloor\right)$$
咱们发现若是狄利克雷卷积前缀很好算的话,积性函数的前缀也能够分块递归来算了。
举几个例子:
1. 求 $S(n)=\sum\limits_{i=1}^n\mu(n)$
上述式子 $$g(1)S(n)=\sum_{i=1}^n(g*\mu)(i)-\sum_{i=2}^ng(i)S\left(\left\lfloor\frac{n}{i}\right\rfloor\right)$$
考虑到 $\sum\limits_{d\mid n}\mu(d)=[n=1]$ ,又因为 $(g*\mu)(n)=\sum\limits_{d\mid n}g(d)\mu\left(\frac{n}{d}\right)$ 。咱们考虑让 $g(n)=1(n)$ ,那么 $(1*\mu)(n)=\sum\limits_{d\mid n}1\cdot\mu(d)=[n=1]$ 。显然这个卷积的前缀为 $\sum\limits_{i=1}^n(g*\mu)(i)=1(n)$ 。
故对于 $\mu$ $$S(n)=1-\sum_{i=2}^nS\left(\left\lfloor\frac{n}{i}\right\rfloor\right)$$
2. 求 $S(n)=\sum\limits_{i=1}^n\varphi(n)$
上述式子 $$g(1)S(n)=\sum_{i=1}^n(g*\varphi)(i)-\sum_{i=2}^ng(i)S\left(\left\lfloor\frac{n}{i}\right\rfloor\right)$$
考虑到 $\sum\limits_{d\mid n}\varphi(d)=n$ ,又因为 $(g*\varphi)(n)=\sum\limits_{d\mid n}g(d)\varphi\left(\frac{n}{d}\right)$ 。咱们考虑让 $g(n)=1(n)$ ,那么 $(1*\varphi)(n)=\sum\limits_{d\mid n}1\cdot\varphi(d)=n$ 。显然这个卷积的前缀为 $\sum\limits_{i=1}^n(g*\varphi)(i)=\frac{n(n+1)}{2}$ 。
故对于 $\varphi$ $$S(n)=\frac{n(n+1)}{2}-\sum_{i=2}^nS\left(\left\lfloor\frac{n}{i}\right\rfloor\right)$$
证实:由
当 $a = b = 1$ 时,代入二项式定理可证实 $1$ 式;当 $a = -1$ , $b = 1$ 时代入二项式定理可证实 $2$ 式;代入 $a = 1$ , $b = -1$ 可获得另外一个意义相同的式子;$(1式+2式) \over 2$ 可证实 $3$ 式。
$C^m_n\equiv C^{\left\lfloor\frac{m}{p}\right\rfloor}_{\left\lfloor\frac{n}{p}\right\rfloor} \times C^{m \mod p} _{n \mod p} \pmod{p}$ , $p$ 为质数。
证实:须要用到多项式同余的那套理论,然而我并不会。
通常的 $Lucas$ 是在模数 $p$ 是质数的条件下适用的。咱们来考虑 $p$ 不是质数的条件。
咱们对 $p$ 进行惟一分解,记 $p=p_1^{k_1}p_2^{k_2}\cdots p_q^{k_q}$ ,因为形同 $p_i^{k_i}$ 的部分是互质的,显然咱们能够用 $CRT$ 合并。
列出方程组: $\left\{ \begin{array}{c} ans\equiv c_1\pmod {{p_1}^{k_1}}\\ ans\equiv c_2\pmod {{p_2}^{k_2}}\\ ...\\ ans\equiv c_q\pmod {{p_q}^{k_q}}\\ \end{array} \right. $ ,对于每一个 $c_i$ ,表示 $C_n^m$ 在 $\mod p_i^{k_i}$ 下的结果。由解的惟一性,咱们能够证实这个 $ans$ 就是咱们要求的。
根据 $C_n^m=\frac{n!}{m!(n-m)!}$ 咱们只要求出 $n!\mod p_i^{k_i},m!\mod p_i^{k_i},(n-m)!\mod p_i^{k_i}$ ,再用逆元的那套理论就能够求 $c_i$ 了。
考虑如何求 $n!\mod p_i^{k_i}$ 。容易发现 $n!=\left(\prod\limits_{j=1}^n j^{[p_i\nmid j]}\right)\cdot\left(p_i^{\left\lfloor\frac{n}{p_i}\right\rfloor}\right)\cdot\left(\left\lfloor\frac{n}{p_i}\right\rfloor\large! \right)$ 上述式子分为三个部分,第一个部分显然在模 $p_i^{k_i}$ 下,是以 $p_i^{k_i}$ 为周期的。能够周期内找循环节算,周期外的暴力算;第二部分能够直接算;第三部分能够递归求解。
另外注意的是求组合逆元的时候,存在阶乘中的某一个数可能还有 $p_i$ 这个质因子,不能直接算。直接把 $p_i$ 所有提出来,最后求完逆元后再补回去。求 $n!$ 内质因子 $p$ 的个数能够用 $\sum\limits_{i=1}^{+\infty} \left\lfloor\frac{n}{p^i}\right\rfloor$ 来求。
1 LL quick_pow(LL a, LL b, LL p) { 2 LL ans = 1; 3 while (b) { 4 if (b&1) ans = ans*a%p; 5 b >>= 1, a = a*a%p; 6 } 7 return ans; 8 } 9 void ex_gcd(LL a, LL b, LL &x, LL &y) { 10 if (b == 0) {x = 1, y = 0; return; } 11 ex_gcd(b, a%b, x, y); 12 LL t = x; x = y, y = t-a/b*y; 13 } 14 LL inv(LL a, LL p) { 15 LL x, y; ex_gcd(a, p, x, y); 16 return (x%p+p)%p; 17 } 18 LL mul(LL n, LL pi, LL pk) { 19 if (!n) return 1; 20 LL ans = 1; 21 for (int i = 2; i <= pk; i++) if (i%pi != 0) ans = ans*i%pk; 22 ans = quick_pow(ans, n/pk, pk); 23 for (int i = 2; i <= n%pk; i++) if (i%pi != 0) ans = ans*i%pk; 24 return ans*mul(n/pi, pi, pk)%pk; 25 } 26 LL C(LL n, LL m, LL pi, LL pk, LL p) { 27 LL a = mul(n, pi, pk), b = mul(m, pi, pk), c = mul(n-m, pi, pk); 28 LL k = 0; 29 for (LL i = n; i; i /= pi) k += i/pi; 30 for (LL i = m; i; i /= pi) k -= i/pi; 31 for (LL i = n-m; i; i /= pi) k -= i/pi; 32 return a*inv(b, pk)%pk*inv(c, pk)%pk*quick_pow(pi, k, pk)%pk; 33 } 34 LL ex_lucas(LL n, LL m, LL p) { 35 LL ans = 0; 36 for (LL i = 2, x = p; i <= x; i++) 37 if (x%i == 0) { 38 LL k = 1; while (x%i == 0) k *= i, x /= i; 39 (ans += C(n, m, i, k, p)*(p/k)%p*inv(p/k, k)%p) %= p; 40 } 41 return ans; 42 }