数论入门

声明:该讲解来自计蒜客,仅供个人学习使用

整除与带余数除法

 

最大公约数

 欧几里得算法

int gcd(int a,int b)
{
    return b? gcd(b,a%b):a;
}

质数

 

int is_prime(int n) {
    for (int i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return 0; // 不是质数
        }
    }
    return 1; // 是质数
}

for (int i = 2; i <= n; ++i) {
    is_prime[i] = 1;
}
for (int i = 2; i <= n; ++i) {
    for (int j = i * 2; j <= n; j += i) {
        is_prime[j] = 0;
    }
}

for (int i = 2; i <= n; ++i) {
    is_prime[i] = 1;
}
for (int i = 2; i * i <= n; ++i) {
    if (is_prime[i]) {
        for (int j = i * i; j <= n; j +=i) {
             is_prime[j] = 0;
        }
    }
}

二分快速幂

int Pow_mod(int a, int b, int mod) {
    if (b == 0) {
         return 1%mod;
    }
    int temp = Pow_mod(a, b/2, mod);
    temp = temp * temp % mod;
    if (b%2 == 1) {
         temp = temp * a % mod;
    }
    return temp;
}

这样我们便得到了 O(lgb) 的时间复杂度的算法计算 a^b次方。

int Pow_mod(int a, int b, int mod){
    int res = 1, temp = a;
    for (; b; b /= 2) {
        if (b & 1) {
            res = res * temp % mod; // 2进制上这一位为1,乘上这一位权值
        }
        temp = temp * temp % mod; // 位数加1, 权值平方
    }
    return res;
}

排列组合

矩阵

struct matrix {
   int n, m;
   int a[100][100];
};
// A.m == B.n
matrix matrix_mul(matrix A, matrix B) {
    matrix C;
    C.n = A.n;
    C.m = B.m;
    for (int i = 0; i < A.n; ++i) {
        for (int j = 0; j < B.m; ++j) {
            C.a[i][j] = 0;
            for (int k = 0; k < A.m; ++k) {
                C.a[i][j] += A.a[i][k] * B.a[k][j];
            }
        }
    }
    return C;
}

int n; // 所有矩阵都是 n * n 的矩阵
struct matrix {
   int a[100][100];
};
matrix matrix_mul(matrix A, matrix B, int mod) {
    // 2 个矩阵相乘
    matrix C;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            C.a[i][j] = 0;
            for (int k = 0; k < n; ++k) {
                C.a[i][j] += A.a[i][k] * B.a[k][j] % mod;
                C.a[i][j] %= mod;
            }
        }
    }
    return C;
}
matrix unit() {
    // 返回一个单位矩阵
    matrix res;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (i == j) {
                res.a[i][j] = 1;
            } else {
                res.a[i][j] = 0;
            }
        }
    }
    return res;
}
matrix matrix_pow(matrix A, int n, int mod) {
    // 快速求矩阵 A 的 n 次方
    matrix res = unit(), temp = A;
    for (; n; n /= 2) {
        if (n & 1) {
            res = matrix_mul(res, temp, mod);
        }
        temp = matrix_mul(temp, temp, mod);
    }
    return res;
}

-

原文地址:https://www.cnblogs.com/jiamian/p/12227652.html