[关闭]
@WangYixu 2018-06-14T13:09:50.000000Z 字数 8676 阅读 822

OI 数学 笔记 算法

数学学习笔记


数论

1.简介

主要研究整数的性质

2.整除

整除的性质

3.素数

也可写作.

素数判定

质因数分解

枚举的所有质数,不断试除至除净.

最后可能会剩一个大的素因子.

4.筛法

埃氏筛

  1. notp[1] = 1;
  2. for (int i = 2; i <= n; i ++)
  3. if (!notp[i])
  4. for (int j = i * i; j <= n; j += i)
  5. notp[j] = 1;

线性筛

约定每个数只被它的最小质因子筛去。

  1. notp[1] = 1;
  2. for (int i = 2; i <= n; i ++) {
  3. if (!notp[i]) pri[++ psz] = i;
  4. for (int j = 1; j <= psz; j ++) {
  5. int k = i * pri[j];
  6. if (k > n) break ;
  7. notp[i * pri[j]] = 1;
  8. if (i % pri[j] == 0) break;
  9. //pri[j]是i的素因子,那么pri[j+1]*i的最小素因子不是pri[j+1],按照约定,跳出循环。
  10. }
  11. }

区间筛

给定,求范围内的素数。

  1. \\预先筛好[1,sqrt(r)]范围内的素数
  2. for (int i = 1; i <= psz; i ++) {
  3. int p = pri[i];
  4. for (int j = (l - 1) / p + 1/*防止下标小于0*/; j <= r / p; j ++)
  5. notp[j * p - l] = 1;
  6. }

5.mod运算

.

6.GCD

欧几里得算法

  1. int gcd(int a, int b) {
  2. return !b ? a : gcd(b, a % b);
  3. }

证明:

推广:

  1. 如果,不合法,输出零。
  2. ,分别唯一分解,对于某个质因子,其指数为,如果,那么的指数只能为,如果,那么中必有一个数的指数为,一个为,一个满足,这样的三元组一共有种;

这里做了一个小改动:直接分解

本来还打了素数表,不知道为什么WA了

  1. inline void factor() {
  2. memset(g, 0, sizeof(g));
  3. memset(l, 0, sizeof(l));
  4. if (L % G) {
  5. printf("0\n");
  6. return;
  7. }
  8. ll ans = 1;
  9. L /= G;
  10. for (register int i = 2; L > 1; ++i) {
  11. int cnt = 0;
  12. while (L % i == 0 && L > 1) {
  13. L /= i;
  14. cnt++;
  15. }
  16. if (cnt) ans *= 6 * cnt;
  17. }
  18. printf("%d\n", ans);
  19. }

扩展欧几里得

求解形如的不定方程。

  1. void exgcd(int a, int b, int& d, int &x, int &y) {
  2. if (!b) x = 1, y = 0, d = a;
  3. else {
  4. d = exgcd(b, a % b, d, y, x);
  5. y -= (a / b) * x;
  6. }
  7. }

该算法解出了的一组解,其通解表示为

模板题

设相遇时间为,那么,两只青蛙相遇可以表示为,即,化简得
扩欧解即可。

转化成

枚举即可。

注意要从最大洞穴编号开始枚举。就这个我WA了3次。

7.同余

同余的性质

逆元

扩欧解即可。

也可以用费马小定理求。

可以在的时间内处理的逆元:

考虑以下式子:

这样就可以O(1)递推了

  1. inv[1] = 1;
  2. for(int i = 2; i <= n; ++i) {
  3. inv[i] = ((-inv[P % i] * (P / i) ) %P+P)% P;
  4. }

费马小定理

费马小定理没有逆定理

素数测试

虽然费马小定理没有逆定理,但是费马小定理的逆否命题是正确的,所以我们可以用费马小定理来验证一个数是否是合数,这样,多次选取a的值,就能大致确定一个数是否是质数。

可惜总有一些数是特殊的,能卡掉这种算法。

所以我们就要使用Miller-Rabin算法

对于一个可能是质数的数,如果它是质数,那么,其必然满足:

而由于二次探测定理,就有

如果余,则可以递归下去检验,如果余,那么停止递归,我们就认为是一个可能的素数。

多次测试,避免偶然性。

实践中多自下而上操作。

考虑构造一个数,满足最小。

那么,由二次探测定理,必然有.

  1. bool Miller-Rabin(int p, int T) {
  2. if (p == 2) return true;
  3. if (p < 2) return false;
  4. int t = p-1, x = 0;
  5. while (!(t&1)) {
  6. t >>= 1;
  7. x++;
  8. }
  9. while (T--) {
  10. int a = rand() % (p-1) + 1;
  11. if(pow_mod(a, t, p) == 1) continue;
  12. flag = 0;
  13. for (int i = 1; i <= x; ++i) {
  14. if (pow_mod(a, (t<<i), p) == p-1) {
  15. flag = 1;
  16. break;
  17. }
  18. }
  19. if (!flag) return false;
  20. }
  21. return true;
  22. }

中国剩余定理

对于模线性方程组:

时有唯一解,

8.整除分块

方法一:枚举,naive!

方法二:整除分块

  1. int ans = 0, n = 100;
  2. for (int i = 1, j; i <= n; i = j + 1) {
  3. j = min(n, (n/(n/i)));//右端点,玄学操作
  4. ans += (n/i)*(j-i+1);
  5. }
  6. printf("%d\n", ans);

转化成,
整除分块,注意到商相同时,后面的求和部分成等差数列,做即可。

  1. ll ans = n * k;
  2. for (ll i = 1, j; i <= n; i = j + 1) {
  3. if(k / i) j = min(n, (k/(k/i)));
  4. else j = n;
  5. ans -= (j-i+1)*(i+j)*(k/i)/2;
  6. }
  7. printf("%lld\n", ans);

题解

9.数论函数

定义域为整数的函数

欧拉函数

基于以下三条定理,我们可以线性的求出欧拉函数表


定理1易证,定理3是欧拉函数的性质,下面给出定理2的证明:

  1. notp[1] = phi[1] = 1;
  2. for (int i = 2; i <= n; i ++) {
  3. if (!notp[i]) pri[++ psz] = i, phi[i] = i - 1;
  4. for (int j = 1; j <= psz; j ++) {
  5. int k = i * pri[j];
  6. if (k > n) break ;
  7. notp[k] = 1;
  8. if (i % pri[j] == 0) {
  9. phi[k] = phi[i] * pri[j]; //mark
  10. break;
  11. } else {
  12. phi[k] = phi[i] * phi[pri[j]];
  13. }
  14. }
  15. }

莫比乌斯函数

可知当有质因子时平方因子时.

莫比乌斯函数可以线性筛

  1. notp[1] = phi[1] = mu[1] = 1;
  2. for (int i = 2; i <= n; i ++) {
  3. if (!notp[i]) pri[++ psz] = i, phi[i] = i - 1, mu[i] = -1;
  4. for (int j = 1; j <= psz; j ++) {
  5. int k = i * pri[j];
  6. if (k > n) break ;
  7. notp[k] = 1;
  8. if (i % pri[j] == 0) {
  9. mu[k] = 0;//有平方因子
  10. break ;
  11. } else {
  12. mu[k] = -mu[i];//无平方因子,多了一个素因子
  13. }
  14. }
  15. }

10.反演

懵逼五四繁衍莫比乌斯反演

理解方式1

有如下两条定理:

理解方式2

重要结论

例题们

解:

解:

以上两个反演十分基础,必须全面理解。

解:


概率与期望


代数

1.排列和逆序对

2.行列式

  1. a[n][n],y[n];
  2. do {
  3. res = 1;
  4. for (int i = 1; i <= n; ++i)
  5. res *= a[i][y[i]];
  6. if(isOdd(y)) res = -res;
  7. ans += res;
  8. } while (next_permuation(y+1, y+n+1))

余子式

Cramer法则

线性方程组的系数行列式时有唯一解
其中为将中的第列换成等号右边的数的行列式。

高斯消元法

3.矩阵

个点的完全图生成树的个数为


计数


杂七杂八

x.线性基

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注