NOIp复习
在放弃集训,又很久没碰OI的情况下,需要改变一下OI学习方式。我决定试一下这种知识点复习方式,向文化课靠拢……
这里将写一些比赛前必须看的复习内容,包括重要结论和模板之类的,希望整理的过程中能有收获。顺序可能随时变动,并且主要根据个人喜好,敬请谅解。
数学
数学部分在联赛中的难度一般不大,但有了去年结论题的教训,千万勿忘打表。规定
$$(a,b)=\gcd(a,b)$$
欧拉函数(phi)
$$\varphi(n)=\sum_{i=1}^n [(i,n)=1]=n\times \prod_{\text{p is prime factor of n}}\frac{p-1}p$$
对于质数$p$有
$$\varphi§=p-1$$
1 | int phi(int n) |
时间复杂度$\mathcal O(\sqrt n)$。
欧拉定理和费马小定理
$$a^{\varphi(b)}\equiv 1 \mod b,(a,b)=1$$
当$p$为质数时,有
$$a^{\varphi§}=a^{p-1} \equiv 1 \mod p,(a,p)=1$$
快速幂(qpow)
求$a^b \mod p$。
注意范围,以及应用费马小定理来处理幂取模和求逆元。
1 | int qpow(long long a, int b, int p) |
若运算复杂度为$\mathcal O(k)$,时间复杂度$\mathcal O(k\log b)$。
扩展欧几里得(exgcd)
求$ax+by=(a,b)$的解。如果右边不等于$(a,b)$,那么无整数解。令$a’=a/(a,b),b’=b/(a,b)$,则x,y也是$a’x+b’y=1$的解,而$x’=x+kb’,y’=y+ka’,k\in \mathbb Z$也是一组解。
1 | int exgcd(int a, int b, int &x, int &y) |
时间复杂度$\mathcal O(\log a)$。
逆元(inv)
求$ax \equiv 1 \mod b$,若$(a,b)\neq 1$无解。当$b$不是质数时,用exgcd解同余方程比求$a^{\varphi(b)-1}$快;当$b$是质数时,求$a^{b-2}$更加方便。
线性逆元
求$1\dots n$在模$p$下的逆元$inv[]$($n<p$)。一般有两种方法。
$$inv[1]=1,inv[i]=(p-p/i)\times inv[p\mod i]$$
另一种不需要记忆,计算阶乘取模$fact[]$,求出$fact[n]$的逆元,然后递推得出阶乘逆元$inv[]$。显然$i$的逆元为$fact[i-1]*inv[i]$。
筛法
求$1\dots n$的质数、每个数的最小质因数、欧拉函数等。一般推荐线性筛,就不写埃氏筛了。
1 | for (int i = 2; i <= n; i++) |
组合数(comb)
求$C_n^m\mod p,m\le n$,超过杨辉三角,下面是一些简单的方法。
如果$p$为质数,且$n,m<p$,直接用阶乘逆元预处理即可。复杂度预处理$\mathcal O(n)$,询问$\mathcal O(1)$,这也是最常用的方法,例如$n=10^6,p=10^9+7$。
1 | int comb(int n, int m) |
如果$p$为质数且较小,用Lucas定理$C_n^m \equiv C_{n\mod p}^{m\mod p} \times C_{n/p}^{m/p} \mod p$。复杂度预处理$\mathcal O§$,询问$\mathcal O(\log n)$,例如$n=10^{18},p=10^6$。
1 | int comb(int n, int m, int p) |
如果$p$为任意数,可以线性筛质因子约分快速幂。复杂度$\mathcal O(n)$,例如$n=10^6$。
1 | int comb(int n, int m) |
如果$p$为任意数,且$m$很小,可以暴力分解质因数。复杂度$\mathcal O(m\sqrt n)$,例如$n=10^9,m=10^3$。