写在前面:这篇文章写了一些基础数学知识,包括数论、数论函数、组合、概率、计算几何等。结论一般来说会有证明,并且结论都加粗显示了。在算法复杂时会有示范代码。
版块I:数论(Number Theory)
一、同余(Coresidual)
同余的简单性质大家都会不讲了,证一下除法原则:
除法原则:若(ac equiv bc pmod p),则(a equiv bpmod {dfrac{p}{gcd(c, p)} })
证明:(ac-bcequiv 0 pmod p)
(c(a - b)equiv 0 pmod p)
(p mid c(a - b))
(dfrac{p}{gcd(c, p)} mid dfrac{c}{gcd(c, p)} (a - b))
因为(dfrac{p}{gcd(c, p)}) 与 (dfrac{c}{gcd(c, p)}) 互质((gcd)的定义)
所以(dfrac{p}{gcd(c, p)} mid (a - b))
(a equiv bpmod { dfrac{p}{gcd(c, p)} })
二、辗转相除法(Euclidean algorithm)
我们这么写程序:(gcd(a, b) = gcd(b, a mod b))
等价于证明:(gcd(a, b) = gcd(b, a - b))
注意到公因数小于等于其最大公约数。
令(d=gcd(a, b), d'=gcd(b, a - b))
(d mid a, d mid b),因此(d mid a - b),所以(dleq d')
(d' mid b, d mid a - b),因此(d mid a),所以(d'leq d)
因此(d=d'),得证
三、扩展欧几里得算法(Extended Euclidean algorithm)
方程 (ax+by=gcd(a, b)) 存在一组整数解 (x, y)。
证明:
若(bx + (a mod b)y = gcd(b, a mod b))有解,进行重组:
(bx + (a - lfloor frac{a}{b} floor imes b)y=gcd(a, b))
(bx + ay - lfloor frac{a}{b} floor imes b imes y=gcd(a, b))
(ay + b(x - lfloor frac{a}{b} floor imes y) =gcd(a, b))
可以构造出(ax+by=gcd(a, b))的解
因此可以一直递归,直到某个数为(0),这时候显然有整数解,所以原方程也是有整数解的
推论:(a)在模(p)意义下存在逆元的条件是(gcd(a, p)=1)
四、欧拉函数(Euler Function)
(1) 到 (n) 中与 (n) 互质的数的个数(欧拉函数)(varphi(n)=nprod_{p_i}(1 - frac{1}{p_i}))
证明:
每个素因子的倍数与 (n) 不互质,应该减去,但是有些数是多个素因子的倍数,因此需要容斥
(varphi(n)=n - lfloor dfrac{n}{p_1} floor - lfloor dfrac{n}{p_2} floor - ... + lfloor dfrac{n}{p_1p_2} floor + ...)
考虑每个素因子要是选,分母乘以它,这一项变号;不选相当于乘以(1)。于是得到上述式子。
证明:与 (n) 互质的数之和为(frac{nvarphi(n)}{2})
若 (gcd(d, n)=1),则 $gcd(n, n - d) = 1 $,即互质的数两两出现,且和为 (n)
可以证明 (d ot = n - d),若相等则 (2d=n),不互质
欧拉定理:若 ((a, m)=1,a^{varphi(m)}equiv 1pmod m)
证明:任取缩系 (r_1, r_2, ..., r_{varphi(m)})
((a, m)=1),则(ar_1, ar_2, ..., ar_{varphi(m)})也是一个缩系
(r_1r_2...r_{varphi(m)}equiv ar_1ar_2...ar_{varphi(m)} pmod m)
每个(r)与(m)互质,存在逆元,两边同时约去,得证
特殊情形:(a^{p-1}equiv 1pmod p)
扩展欧拉定理:(a^bequiv a ^{min(b, bmod varphi(m)+varphi(m))} pmod m)
证明:待更
五、中国剩余定理及拓展(Chinese Remainder Theorem and Its Expansion)
求解线性同余方程组
1. 若(m_1, m_2, cdots, m_n)两两互质
使用中国剩余定理crt构造。
令(M = prod m_i, k_i=frac{M}{m_i}),记(k_i^{-1})表示(k_i)在(mod m_i)意义下的逆元,
方程组的解为:(x=sum_{i = 1}^n a_i k_i k_i^{-1})
每个(a_i)的系数,当不是(mod m_i)的时候都会是(0)(整除),(mod m_i)的时候为(1)(逆元的定义),巧妙构造出解
2. 若(m_1, m_2, cdots, m_n)不一定两两互质
使用拓展中国剩余定理
考虑如何合并方程(x equiv a pmod b,xequiv cpmod d)
令(x=bt + a)
$bt + a equiv cpmod d $
(bt equiv c - a pmod d)
使用exgcd解出 (tequiv t_0pmod {dfrac{d}{gcd(b,d)}})
再带回去就能得到 (x)
于是我们可以通过(n-1)次合并解出上述同余方程组
若exgcd时出现无解就意味着同余方程组无解
六、离散对数:BSGS和exBSGS
离散对数:(a^xequiv b pmod p)
1. (gcd(a, p) = 1)时:BSGS算法
令(m = lceil sqrt p ceil) ,
假设(x)是解,则(x)一定可以表示为(x = mq + r,qin[0, m], r in[0, m - 1])(带余除法)
(a^{mq+r}equiv b pmod p)
(a^{mq}equiv ba^{-r} pmod p)
我们枚举(q)把左边存入hash表,再枚举右边的(r),查询有没有对应的(q)
注意最好手写hash表,或者unordered_map
复杂度为(O(sqrt p log p))
实际中其实可以灵活调整(m)的大小优化复杂度
2. 若(gcd(a, p) ot = 1)时候,使用exBSGS算法。
令(d = gcd(a, p)),等式两边不断同时约去(d),直到(d=1)
起初,(a^xequiv b pmod p)
约一次:(a^{x-1}dfrac{a}{d}equiv dfrac{b}{d} pmod {dfrac{p}{d}})
直到(a,p)互质以后:(a^{x-t}dfrac{a^t}{prod d}equiv dfrac{b}{prod d} pmod {dfrac{p}{prod d}})
把左边(dfrac{a^t}{prod d})移到右边(此时一定存在逆元),使用BSGS求解,然后答案加上 (t)。
注意约的时候要特判,(d) 不整除 (b) 无解。另外如果出现左边等于右边,答案就是(t),这是用于加速的特判。
每次约分(p)至少减小一半((dgeq 2)),所以这个过程只是带一个(log)而已
复杂度为(O(sqrt p log^2 p))
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
namespace Map {
const int mod = 76543;
const int N = 1e5 + 10;
int cnt, hd[mod], nxt[N], fir[N], sec[N];
void clr() {
fill(hd, hd + mod, -1); cnt = 0;
}
void ins(int x, int y) {
int k = x % mod;
fir[cnt] = x; sec[cnt] = y; nxt[cnt] = hd[k]; hd[k] = cnt ++;
}
int find(int x) {
for(int i = hd[x % mod]; ~ i; i = nxt[i])
if(fir[i] == x) return sec[i];
return -1;
}
}
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
void exgcd(int a, int b, int &x, int &y, int &g) {
if(!b) x = 1, y = 0, g = a;
else exgcd(b, a % b, y, x, g), y -= a / b * x;
}
int qpow(int a, int b, int p) {
int ans = 1;
for(; b >= 1; b >>= 1, a = 1ll * a * a % p)
if(b & 1) ans = 1ll * ans * a % p;
return ans;
}
int inv(int a, int p) {
int x, y, g; exgcd(a, p, x, y, g);
return g == 1 ? (x % p + p) % p : -1;
}
int logM(int a, int b, int p) { //a^x c = b (mod p), (a, p) = 1
Map :: clr();
int m = (int) ceil(sqrt(p + 0.5));
int aM = qpow(a, m, p), t = 1;
for(int i = 0; i <= m; i ++) {
if(-1 == Map :: find(t)) Map :: ins(t, i);
t = 1ll * t * aM % p;
}
int q = b, inv_a = inv(a, p), ans = -1;
for(int i = 0; i < m; i ++) {
if(~ (t = Map :: find(q))) {
int r = t * m + i;
if(ans == -1 || ans > r) ans = r;
}
q = 1ll * q * inv_a % p;
}
return ans;
}
int exlogM(int a, int b, int p) { //a^x = b (mod p)
if(b == 1) return 0;
int d = gcd(a, p), t = 0, l = 1;
while(d > 1) {
if(b % d) return -1;
b /= d; p /= d; t ++;
l = 1ll * l * (a / d) % p;
if(l == b) return t;
d = gcd(a, p);
}
b = 1ll * b * inv(l, p) % p;
int q = logM(a, b, p);
return ~ q ? q + t : -1;
}
int main() {
int x, z, k;
while(~ scanf("%d%d%d", &x, &z, &k) && x && z && k) {
int res = exlogM(x % z, k, z);
if(res == -1) puts("No Solution");
else printf("%d
", res);
}
return 0;
}
七、二次剩余的Cipolla算法
1. 一些定义
二次剩余:若(x^2equiv a pmod p)有解,则称(a)是(p)的二次剩余。
感性理解就是(a)在模(p)意义下可开方。
定义勒让德符号:
注意:
这里仅讨论 (p) 是奇质数的情况,其他情况过于毒瘤,可以参考miskcoo : 二次剩余及计算方法学习
2. 欧拉判别法
证明:若 (pmid a),显然成立
若 (a) 是 (p) 的二次剩余,则存在 (x^2equiv a pmod p)
((x^2)^{frac{p-1}{2}}equiv a^{frac{p-1}{2}})
根据费马小定理,(x^{p-1}equiv 1pmod p)
得到 (a^{frac{p-1}{2}}equiv 1 pmod p)
若 (a) 不是 (p) 的二次剩余,则不存在 (x,x^2equiv apmod p)
则对于每个 (xin[1, p)),都能找到对应的 (yin[1,p),y ot=x) 满足 (xy=a)
于是我们可以把 ([1, p)) 中的数两两配对,一共(frac{p-1}{2})对,每对乘积为 (a)
得到等式 ((p-1)!equiv a^{frac{p-1}{2}})
根据威尔逊定理,((p-1)!equiv -1 pmod p)
得到 (a^{frac{p-1}{2}}equiv -1 pmod p)
综上,得证
3. Cipolla 算法
使用该算法求:(x^2equiv npmod p)的一个解(x)
首先随机出来一个(a),满足((a^2-n)^{frac{p-1}{2}}equiv -1 pmod p)
期望(2)次随机出来((a^2)是(n)二次剩余的时候会再随机一次,即(a^4equiv n pmod p),这样的(a)不超过(4)个)
然后为了强行开根,设(omega=sqrt{a^2-n})为虚数单位(类比(i=sqrt{-1}))
结论:(x=(a+omega)^{frac{p+1}{2}})
证明:
上面的证明用到了几个定理
- ((a+omega)^pequiv a^p+omega^p):二项式定理展开,除了首尾项,都含有(p)因子
- (omega^pequivomega(omega^2)^{frac{p-1}{2}} equiv omega(a^2-n)^{frac{p-1}{2}} equiv-omega)
据说根据拉格朗日定理可得最后答案虚部为(0),然而不会拉格朗日定理(
然后就做完了。还是放个代码吧(虽然是乱写的)。
namespace cipolla {
const int mo = 1e9 + 9;
int a, t;
struct Node {
int x, y;
Node operator * (const Node &b) const {
return (Node) {
(int) ((1ll * x * b.x % mo + 1ll * y * b.y % mo * t % mo) % mo),
(int) ((1ll * x * b.y % mo + 1ll * y * b.x % mo) % mo)
};
}
};
int qpow(int a, int b) {
int ans = 1;
for(; b >= 1; b >>= 1, a = 1ll * a * a % mo)
if(b & 1) ans = 1ll * ans * a % mo;
return ans;
}
Node nqpow(Node a, int b) {
Node ans = (Node) {1, 0};
for(; b >= 1; b >>= 1, a = a * a)
if(b & 1) ans = ans * a;
return ans;
}
int sqrt(int n) {
a = 1; srand(time(0));
while(qpow(((t = (1ll * a * a % mo - n) % mo + mo) % mo), (mo - 1) / 2) != mo - 1)
a = 1ll * rand() * rand() % mo;
return nqpow((Node) {a, 1}, (mo + 1) / 2).x;
}
}
八、以原根为基础的同余
1. 一些定义
阶:若 ((a, p) = 1),满足 (1leq x < p,a^xequiv 1 pmod p) 的最小正整数 (x) 称为 (a) 在模 (p) 的阶,记为 ( ext{ord}_p(a)),也有学者记做 (delta_{p} (a))。
感性理解:阶就是最小几次方变成1。
根据欧拉定理,阶一定存在
原根:若 (g) 在模 (p) 的阶为 (varphi(p)),则称 (g) 为 (p) 的原根
感性理解:原根是一个替代品,因为它的次幂能遍历 (p) 的缩系(证明在后面)
指标:若 (0 leq x < varphi(p), g^xequiv apmod p),称 (x) 为以 (g) 为底模 (p) 的一个指标
2. 性质
下面若无特殊说明,(p) 为模数,(x) 表示 ( ext{ord}_{p}(a)),(g) 表示 (p) 的一个原根。
性质1:(a^{u}equiv a^vpmod p)当且仅当(uequiv vpmod x)
证明:
-
充分性:显然
-
必要性:设(u>v),记录差(l=u-v),则(a^lequiv1pmod p)
令(l=kx+r(0leq r<x)):(a^{kx+r}equiv 1pmod p)
((a^{x})^k a^requiv 1pmod p)
(a^{r}equiv 1pmod p)
根据(0leq r<x)和阶的定义,(r=0),得(x mid (u - v))。
性质1的特殊情形:(a^uequiv 1)当前仅当(xmid u)
性质1的推论1:(a,a^2,...,a^{x})两两(mod p)不同余
性质1的推论2:(xmid varphi(p))
性质(2):只有(2,4,t^n, 2t^n)有原根((t)是奇质数)
证明:
由于这个证明不在高中数学联赛要求范围内,我们不需要会(雾)
性质3:(g^t (tin N))遍历(p)的缩系。
证明:(g^t)有 (varphi(p)) 种取值我们能根据定义得到。
由于 ((g,p)=1),所以 ((g^t,p)=1),这 (varphi(p)) 种取值恰是缩系。
性质4:若(p)有原根,则原根个数为(varphi(varphi(p)))
证明:找一个任意原根(g),那么对于所有的原根(g'),
(g')可以表示成(g^kmod p),其中(1leq kleq varphi(p))
根据上面的性质我们知道:({g,g^2,...,g^{varphi(p)}})为(p)的缩系,且(g^t)的循环的,以(varphi(p))为最小正周期。
同时(g')也是原根,则({g',g'^2,...,g'^{varphi(p)}})也为(p)的缩系
代入得到:({g^k,g^{2k},...,g^{varphi(p)k}})是(p)的缩系
即让({k, 2k, ..., varphi(p)k})两两(mod varphi(p))不同
也就是让({k, 2k, ..., varphi(p)k})取遍(varphi(p))的缩系
假设k是不满足条件的,即存在(ik=jkpmod {varphi(p)})
不妨设(i>j),则(varphi(p)mid (i-j)k)
除去gcd以后:(frac{varphi(p)}{gcd(varphi(p),i-j)}|k)
注意到(i-jin[1,varphi(p)-1])
(frac{varphi(p)}{gcd(varphi(p),i-j)}) 取遍了 (varphi(p)) 的约数 (d(d>1))
因此(k)若不满足条件,则 (gcd(k,varphi(p))>1)
反之,(gcd=1) 时 (k) 一定满足条件
这样的 (k) 有(varphi(varphi(p)))个,对应原根也就有这么多个。
性质(5):若 (g) 是原根,且 (gcd(varphi(p),x)=1),则 (g^x) 是原根
证明:实际上就是指数上完全剩余系成一个互质的数不变。
3. 求解原根和阶
求阶:枚举 (varphi(p)) 的约数暴力检验
求最小原根:分布挺密集,暴力求
快速判断的方法?试除法!
把 (varphi(p)) 质因数分解得到质因数集合 ({p_1,p_2,...,p_k})(易知集合大小不超过 (log p))
若 (g) 满足 (forall iin[1,k]),(g^{frac{varphi(p)}{p_i}} ot = 1),则(g)是原根,否则不是。
正确性挺显然的,若 ( ext{ord}_p(g)<varphi(p)),这样能检验出来。
求所有原根:先求最小原根 (g),然后 (g^t,gcd(t,varphi(p))=1) 即为所有原根。
4. K次剩余方法
用于求满足 (x^kequiv apmod p) 的解,(p) 是质数
求一个任意原根 (g),则解 (x) 一定可以表示成 (g^tmod p(1leq t < p))。
(a) 也用原根表示:(a = g^smod p),这个可以BSGS求出 (s)
然后 (x^kequiv apmod p) 就变成了 (g^{tk}equiv g^{s})
也就是 (tkequiv spmod {p-1})
然后就是 simple 的同余方程问题,随便求出 (t) 然后快速幂求 (x=g^t) 没了。
【还未实现过,留坑】
若要求k次剩余所有解?
【留坑】
九、常见算法:质数判定与大数因子
Miller Rabin
:质数检测
若 (p) 是质数,则有:
- 费马小定理 (a^{p-1} equiv 1 pmod p)
- 二次探测原理:若 (a^2equiv 1 pmod p),那么 (a equiv pm 1 pmod p)。
我们利用这个原理对待监测的质数进行初步检验。
随机选取一个 (a),把 (p - 1) 分解成 (2^k imes t) 的形式,其中 (2 ot mid t)。
令变量 (x = a^t) 开始,进行 (k) 次平方,每次令 (x leftarrow x^2),若 (x = 1),查看上次的 (x) 是否是 (p - 1) 或 (1),不是直接返回 false。平方完以后的 (x) 是 (a^{p - 1}),若 (x = 1) 返回 true,否则返回 false。
据说 (n) 次测试正确率 (1 - left(dfrac{1}{4} ight)^n) 。我们一般选取前 (10) 个质数作为上面的 (a),这样据说在 long long 范围内是不会出错的。
Pollard-Rho
算法:
引理:若 (k) 个 ([0,n-1]) 的随机变量,有两个变量相等,(k) 的期望是 (mathcal O(sqrt n))。
先我们要实现一个函数,能快速求出大数的一个因子。先用Miller Rabin
判掉素数。我们构造一个模 (n) 意义下随机函数 (f(x) = x^2 + c),那么 (f(x),f(f(x)),...) 一定构成一个环。然后我们用两个 (a,b),初始随机 (a) 令 (b = f(a)),然后每次 (a=f(a),b= f(f( b))),即第一个人走一步,第二个人走两步,他们最终会在环上相遇。再次过程中求 $d=gcd(|a-b|,n) $,若 (d=n) 说明 (a=b),退出函数进行下一轮分解;若 (d>1),则 (d) 就是个 (n) 的因数,直接返回。这样期望轮数是多少?考虑 (n) 的最小素因子 (p (pleq sqrt n)),(xequiv ypmod p) 的时候 (d > 1),根据引理我们需要 (mathcal O(sqrt p)) 的时间相撞,也就是总复杂度 (mathcal O(n^{frac{1}{4}} log n)),log 是 gcd 的复杂度。
如何消去 log?考虑取伐值 (c = 128),我们把 (c) 轮的 (|a-b|) 乘起来 (mod n),若 (c=1) 显然互质直接跳过去,若 (c ot = 1) 说明 (d > 1),再重新跳一遍找到 (d)(有点类似分块),这样 log 就消失了。
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
typedef unsigned uint;
ll rnd() {
static uint seed = 1999999;
seed ^= seed << 14;
seed ^= seed >> 3;
return seed;
}
ll mul(ll a, ll b, ll p) {
ll d = (ll) floor(a * (long double) b / p);
ll res = (a * b - d * p) % p;
if(res < 0) res += p;
return res;
}
ll qpow(ll a, ll b, ll p) {
ll ans = 1;
for(; b; b >>= 1, a = mul(a, a, p))
if(b & 1) ans = mul(ans, a, p);
return ans;
}
int base[10] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29}, S = 10;
bool check(ll a, ll x, int t, ll n) {
ll tmp = qpow(a, x, n), last;
while(t --) {
last = mul(tmp, tmp, n);
if(last == 1 && tmp != 1 && tmp != n - 1) return false;
tmp = last;
}
return tmp == 1;
}
bool MR(ll n) {
for(int i = 0; i < S; i ++)
if(n % base[i] == 0) return n == base[i];
ll t = 0, m = n - 1;
while(!(m & 1)) m >>= 1, t ++;
for(int i = 0; i < S; i ++)
if(!check(base[i], m, t, n)) return false;
return true;
}
#define f(x) ((mul(x, x, n) + c) % n)
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a % b);
}
ll PR(ll n) {
ll c = rnd() & 1023;
ll a = rnd() % n, b = f(a), tmp;
for(;;) {
ll prod = 1, s = a, t = b;
for(int i = 0; i < 128; i ++) {
prod = mul(prod, abs(s - t), n);
s = f(s); t = f(f(t));
}
ll d = gcd(n, prod);
if(d == 1) { a = s; b = t; continue ; }
for(int i = 0; i < 128; i ++) {
d = gcd(n, abs(a - b));
if(d > 1) return d;
a = f(a); b = f(f(b));
}
}
return n;
}
ll calc(ll n) {
if(MR(n)) return n;
ll d = 0;
while(n == (d = PR(n))) ;
return max(calc(d), calc(n / d));
}
int main() {
int T; scanf("%d", &T);
while(T --) {
ll x, ans;
scanf("%lld", &x); ans = calc(x);
if(ans == x) puts("Prime");
else printf("%lld
", ans);
}
return 0;
}
版块II:数论函数
一、狄利克雷卷积(Dirichlet Convolution)
定义狄利克雷卷积:
二、积性函数
若满足((a,b)=1),(f(a)f(b)=f(ab))的数论函数(f)叫做积性函数
性质(1):若(f, g)为积性,(f*g)也为积性
证明:(a,b)为任意互质正整数,((f*g)(a)(f*g)(b)=sum_{d|a} f(d)g(frac{a}{d})sum_{d'|b} f(d')g(frac{b}{d'}))
考虑到对于每一对(d,d'),都满足((d,d')=1),且乘积(dd')取遍(ab)不同的约数,
根据(f(d)g(frac{a}{d})f(d')g(frac{b}{d'})=f(d)f(d')g(frac{b}{d'})g(frac{a}{d})=f(dd')g(frac{ab}{dd'}))
得((f*g)(a)(f*g)(b)=(f*g)(ab))
结论1:(varphi*1=id)
证明:
先令(f(n)=sum_{d|n}varphi(d)),证明(f)为积性函数
设(n, m)互质:
现在证明(f(n)=n),只需证明(f(p^c)=p^c)。
得证。
三、线性筛
线性筛的核心思想是一个合数(x=prod_{i=1}^kp_i^{c_i}),在(y=p_i^{c_i-1}prod_{i=2}^kp_i^{c_i})被筛去
积性函数两种筛法:
- 考虑(f(p^c))到(f(p^{c+1}))
- 考虑找到(k|i,(k,p)=1),(f(ip)=f(k)f(frac{ip}{k}))
四、莫比乌斯反演(Mobius Inversion)
第一种形式:(狄利克雷卷积的形式)
(f(n)=sum_{d|n}g(d)Leftrightarrow g(n) = sum_{d|n}f(d)mu(frac{n}{d}))
第二种形式:(更为常用)
(f(n)=sum_{n|d} g(d) Leftrightarrow g(n)=sum_{n|d}mu(frac{d}{n})f(d))
证明:
最后一项,只有(frac{u}{n}=1)时为(1),其他情况为(0),得证。
套路:
- 枚举最大公约数(d)
- 枚举两个数的乘积(T)
- 转成下取整乘卷积函数g的结构,回答可以(O(sqrt n)),预处理暴力(O(nlog n))或(O(n))线筛
五、杜教筛
求(S(n)=sum_{i=1}^n f(i))
若是(f)是积性函数,并且你能找到一个函数(g),满足(g(1) ot=0),(g)和(f*g)(记作函数(h))能快速求和,就能使用杜教筛
把关于(S(n))的一项拿出来,再通过小学数学变形得:
这个直接记忆化求是(O(n^{frac{3}{4}})),用定积分可以求得。如果预处理前(n^{frac{2}{3}})项,复杂度就是(O(n^{frac{2}{3}}))
版块III:组合(Combinatorial Mathematics)
一、二项式定理
证明用组合意义好证
二、容斥(Inclusion-Exclusion Principle)
两个常用基本式:
版块IV:计算几何(Computing Geometry)
- 判断向量共线:(vec a cdot vec b =0)
- 判断点(P)是否在线段(AB)上:(vec {AP} imes vec{BP}=0,vec {AP}cdot vec{BP}<0)
- 判断线段严格相交:每条线段两个端点分别在另个线段两侧
- 判断线段不严格相交:先判严格相交,再判有没有一个端点在另一条线段上的情况
- 判断直线线段相交:用直线代表向量判断线段两个端点在其两边
- 求交点:用相似三角形相关知识。
- 判断多边形凹凸:每(3)个相邻点判断叉积是否都同符号((0)忽略)
- 判断点在多边形内:叉积判断
- 求凸包:求出上下凸壳合起来
- 求点到线段距离:先点积判断夹角,然后直接求/叉积求距离
- 求线段交点:使用把直线用式p + kv表示,其中p为点,v为向量
Pick定理:对于顶点为格点的简单多边形,(A= i + frac{b}{2} - 1),(A)为面积,(i)为内部整点数目,(b)为边上整点数目。
欧拉公式:(V - E + F = 2)
多边形的核:能看到多边形任意位置的区域(一般对凹多边形求核)。半平面交。
半平面交:S&I算法。
核心思想是极角排序(相同极角取限制更紧的向量)然后用类似求凸壳的做法,每次加入一个向量表示半平面,若队尾两向量交点不在该半平面范围内就弹队尾。然后再查看队头是否被影响。
最后再用队头限制队尾。若队元素<=2说明不存在半平面交。
线段平移
对于向量((x,y))有((y,-x),(-y,x))和它垂直,转化成单位向量,再乘以距离平移(d),得到转移向量。然后线段端点加上转移向量。
版块V:概率期望(Probability and Expectation)
一、离散概率(Discrete Probability)
基本事件(Basic Event):一个仅在样本空间中单个结果的事件,也称样本点
随机事件(Random Events):由某些基本事件构成的集合,用(E)表示
样本空间(Sample Space):随机事件(E)的所有基本结果组成的集合为(E)的样本空间,用(S)表示
概率的组合计数求法:如果(S)由有限个等概率基本事件组成,那么随机事件(E)的概率为(P(E)=frac{|E|}{|S|})
条件概率:(P(A | B)=frac{P(AB)}{P(B)})
中文表述即:在事件B已经发生的前提下,事件A发生的概率,等于AB同时发生的概率除以B发生的概率。
贝叶斯公式:(P(A|B)=frac{P(B|A)P(A)}{P(B)})
全概率公式:(P(B)=sum_{i=1}^n P(B|A_i)P(A_i))
上面几个公式理性理解一下都挺对的,没啥好说。
二、期望
设(x)是离散型随机变量。
期望的定义:(E(x)=sum_{}V_iP_i)。意思就是每个可能的值乘以出现的概率再求和。
期望的线性性证明:(E(x) + E(y) = E(x + y))
通过定义可证。