noip 数学整理
// 质数判定 (1) 暴力 bool check(int x) { for (int i = 2; i * i <= x; ++i) if (x % i == 0) return 0; return 1; } (2)miller_rabin bool check(LL a) { for (int i = 0; i < 12; ++i) { if(f[i] >= a) break; if(Qpow(f[i], a - 1, a) != 1) return 0; LL pp = a - 1; while(pp % 2 == 0) { pp /= 2; LL y = Qpow(f[i], pp, a); if(Qmul(y, y, a) == 1 && y != 1 && y != a - 1) return 0; } } return 1; } //n的所有约数 vector <int> a; for (int i = 2; i * i <= n; ++i) { if (n % i == 0) { a.push_back(i); if (i * i != n) a.push_back(n / i); } } //分解质因数 vector <int> p, c; for (int i = 2; i * i <= n; ++i) { if (n % i == 0) { p.push_back(i); int cnt = 0; while (n % i == 0) ++ cnt, n /= i; c.push_back(cnt); } } if (n > 1) p.push_back(n), c.push_back(1); //线性筛 (1)筛质数 for (int i = 2; i <= lim; ++i) { if (!vis[i]) pri[++ cnt] = i; for (int j = 1; j <= cnt && i * pri[j] <= lim; ++j) { vis[i * pri[j]] = 1; if (i % pri[j] == 0) break; } } (2)筛欧拉函数 phi[1] = 1; for (int i = 2; i <= lim; ++i) { if (!vis[i]) pri[++ cnt] = i, phi[i] = i - 1; for (int j = 1; j <= cnt && i * pri[j] <= lim; ++j) { vis[i * pri[j]] = 1; if (i % pri[j] == 0) { phi[i * pri[j]] = phi[i] * pri[j]; break; } phi[i * pri[j]] = phi[i] * phi[pri[j]]; } } (3) 筛约束约数个数 记t[i]为i的约数个数,e[i]为i的最小素因子的个数 因为是线性筛,每个数只被它最小的质因子筛到,所以 a pri[j]是i*pri[j]的最小质因子 b 如果i是pri[j]的倍数,pri[j]也是i的最小质因子 <1> i是素数,t[i] = 2, e[i] = 1 <2> i是pri[j]的倍数 t[i * pri[j]] = t[i] / (e[i] + 1) * (e[i] + 2) e[i] = e[i] + 1 <3> i不是pri[j]的倍数 t[i * pri[j]] = t[i] * t[pri[j]] e[i * pri[j]] = 1 for (int i = 2; i <= lim; ++i) { if (!vis[i]) pri[++ cnt] = i, t[i] = 2, e[i] = 1; for (int j = 1; j <= cnt && i * pri[j] <= lim; ++j) { vis[i * pri[j]] = 1; if (i % pri[j] == 0) { e[i * pri[j]] = e[i] + 1; t[i * pri[j]] = t[i] / (e[i] + 1) * (e[i] + 2); break; } e[i * pri[j]] = 1; t[i * pri[j]] = t[i] * t[pri[j]]; } } (4)筛约数和 记t[i]为i的约数和,e[i]为i的最小素因子的那一项等比数列 t[i] = (1 + p1 + p1^2 + ...)(1 + p2 + p2^2 + ....) ...(1 + pn + pn^2 + ...) e[i] = (1 + p1 + p1^2 + ...) 因为是线性筛,每个数只被它最小的质因子筛到,所以 a pri[j]是i*pri[j]的最小质因子 b 如果i是pri[j]的倍数,pri[j]也是i的最小质因子 <1> i是素数,t[i] = i + 1, e[i] = i + 1 <2> i是pri[j]的倍数 t[i * pri[j]] = t[i] / e[i] * (e[i] * pri[j] + 1) e[i * pri[j]] = e[i] * pri[j] + 1 <3> i不是pri[j]的倍数 t[i * pri[j]] = t[i] * (pri[j] + 1) e[i * pri[j]] = pri[j] + 1 for (int i = 2; i <= lim; ++i) { if(!vis[i]) pri[++ cnt] = i, e[i] = t[i] = i + 1; for (int j = 1; j <= cnt && i * pri[j] <= lim; ++j) { vis[i * pri[j]] = 1; if (i % pri[j] == 0) { t[i * pri[j]] = t[i] / e[i] * (e[i] * pri[j] + 1); e[i * pri[j]] = e[i] * pri[j] + 1; } t[i * pri[j]] = t[i] * (pri[j] + 1); e[i * pri[j]] = pri[j] + 1; } } //ECGCD void Exgcd(int a, int b, int &x, int &y) { if (b == 0) {x = 1; y = 0; return;} Exgcd(b, a % b, y, x); y -= a / b * x; } 方程 ax + by = c有解, 当且仅当 gcd(a, b) | c d = gcd(a, b) a /= d, b /= d, c /= d 通解: x = x * c + k * b, y = y * c - k * a 最小正整数解 x *= c, x = (x % b + b) % b //线性同余方程 求解 ax=b(mod m) 转化为:ax + my = b tips:求解 ax + by = c时 若 a < 0, 则 a = -a, c = -c //线性同余方程组 x = b1 (mod a1) x = b2 (mod a2) b1 + a1 * x1 = b2 + a2 * x2 a1 * x1 + a2 * x2 = b2 - b1 解出最小的正整数解x' 得到新方程 x = (a1 * x' +b1) (mod lcm(a1, b2)) LL excrt() { LL M = a[1], B = b[1], x, y; for (int i = 2; i <= n; ++i) { LL C = b[i] - B; LL d = gcd(M, a[i]); if (C % d) return -1; exgcd(M, a[i], x, y); x = Mul(x, C / d, a[i] / d); B += x * M; M = M / d * a[i]; B = (B % M + M) % M; } return B; } //欧拉函数 phi[i]表示1...i中与i互质数的个数 i = p1 ^ a1 * p2 ^ a2 *...pn ^ a phi[i] = sum{i / pj * (pj - 1)} //欧拉定理 当gcd(a, n) = 1时, a ^ phi[n] = 1 (mod n) 推论 <1> 若gcd(a, n) = 1, 则a ^ b = a ^ (b % phi[n]) (mod n) <2> 若b > phi[n], 则a ^ b = a ^ (b % phi[n] + phi[n]) (mod n) //费马小定理 <1> p是质数,gcd(a, p) = 1, 则a ^ (p - 1) = 1 (mod p) <2> p是质数,对于任意a, a ^ p = a (mod p) //乘法逆元 a * x = 1 (mod m) x 为 a 在mod m意义下的逆元 求法 <1> m 为质数 pow(a, m - 2) 为逆元 <2> ax + bm = 1, exgcd求解即可 <3> 递推 inv[1] = 1, inv[i] = (p - p / i) * inv[p % i] //组合数 C(n, m) = n! / (m! * (n - m)!) 递推 : c[0][0] = 1; for (int i = 1; i <= n; ++i) { c[i][0] = c[i][i] = 1; for (int j = 1; j <= i - 1; ++j) c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod; } //二项式定理 (a + b) ^ n = sum {C(n, i) * a ^ i * b ^ (n - i)} (0 <= i <= n) //卡特兰数 P(n) = C(2n, n) - C(2n, n - 1) = 1 / (n + 1) * C(2n, n) 前几项:(n从0开始) 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786 递推: P0 = 1 <1> Pn = sum {Pi * Pn - i + 1} (0 <= i <= n - 1) <2> Pn+1 = 2 * (2n + 1) / (n + 2) * Pn 奇卡特兰数满足 n = 2 ^ k - 1 https://quincyqiang.cn/2017/08/24/06-%E5%8D%A1%E7%89%B9%E5%85%B0%E6%95%B0/ http://blog.miskcoo.com/2015/07/catalan-number
选择了oi,只便风雨兼程罢!!!!!