分享|【数论概论】第四部分
554
2024.05.10
2024.05.13
发布于 未知归属地
  1. 第七章 因数分解与算数基本定理

    1. 习题7.1
    2. 习题7.2
    3. 习题7.3
    4. 习题7.4
    5. 习题7.5
    6. 习题7.6
    7. 习题7.7
    8. 代码-分解质因数
    9. 伯努利数
    10. 代码-伯努利数
  2. 第八章 同余式

    1. 习题8.1
    2. 习题8.2
    3. 习题8.3
    4. 习题8.4
    5. 习题8.5
    6. 习题8.6
    7. 习题8.7
    8. 习题8.8
    9. 习题8.9
    10. 习题8.10
    11. 代码-一元一次同余方程
    12. 代码-整系数多项式同余方程
  3. 其他

第七章 因数分解与算数基本定理

习题7.1

​ 假设,进而设 整除乘积 . 证明 必整除 .

证:
.

习题7.2

​ 假设 ,进而设. 证明乘积.

证:

习题7.3

​ 设 为奇数, , 证明

两两互素,即它们中的每一对都互素。在证明勾股定理(定理 )时需用到这个结论。(提示:假设有一个公素因数, 应用引理:如果一个素数整除某个乘积,则它必整除其中一个因数。)

证:(1)假设 ,不妨设,则, 又 ,得出,这与​矛盾。 是奇数。
(2) 假设,不妨设,令,则。根据假设可得矛盾。易证均为奇数时, .
(3) ,证明同(1)

习题7.4

​ 给出下述公式的归纳证明。

  • (a)
  • (b)
  • (c)
  • (d)

(a)
(b)
(c)
(d)

​ 引申:可使用算两次的思想得出一些其他和式的公式。一时兴起算的,发现并不存在某种特定规律,就没往后算了。

习题7.5

​ 本习题要求你继续研究区域。牢记你所做的,本题中假设奇数不存在!

  • (a) 叙述所有素数。
  • (b) 证明每个偶数可分解为素数的乘积。(提示:模仿普通数这个事实的证明)
  • (c) 我们看到 有三种分解法分解成素数的乘积。求有两种不同分解法分解成素数乘积的最小数。 是有三种分解法的最小数吗?求有四种分解法的最小数。
  • (d) 整数 金有一种分解法分解成素数的乘积:. (像通常一样,我们认为是相同的分解。)求仅有一种分解法分解成素数乘积的所有偶数。

(a) 在区域:无法分解为 数乘积的数。扩充到整数区域便于记忆的定义,所有质因子中的个数仅有一个的偶数。
(b) 本身是素数,得证。假设当时,均可被分解为-素数的乘积,若-素数,得证,反之可以被分解为数乘积,不妨令,显然,同理,得证。
(c) (1)引入奇数以便于理解的写法,
(2) 是最小的。
(3)
(d) 引入奇数以便于理解的写法,

习题7.6

​ 欢迎进入 世界,这里只有被 除余 的正整数。换句话说,数是

(另一种叙述是形如 的数。)在 世界中,我们不可能把数相加,但可以把数相乘,因为如果 都被 除余 ,则它们的乘积也是这样。(你知道为什么成立吗?)如果对某 ,则称 整数 . 如果因数仅为 与它自身,则称 素数。(当然,我们不认为 本身是 素数。)

  • (a) 求前 素数。
  • (b) 求有两种不同分解法分解成素数乘积的.

(a) 质数筛法可得:

(b) 构造:

习题7.7

​ 编写将(正)整数 分解成素数乘积的程序。(如果 ,确保转到出错信息而不是出现死循环)。表示 的因数分解的简便方法是 阶矩阵。因此,如果

则将 的分解存储成矩阵

(如果你的计算机不允许动态存储分配,则必须确定允许存储多个因数的预存量)

  • (a) 编写程序,通过试除每个可能因数 分解 . (这是一种极其低效的方法,但常用作初学习题)

  • (b) 修改程序存储前 个(或更多)素数,在找最大素因数前先将 除去这些素数。如果你不管 倍数的,而只把较大的 作为可能的因数,那么可提高程序运行速度。利用 不能被 之间的任何整数整除时 必为素数的事实,也可提高效率。使用你的程序求 间所有整数的完全因数分解。

  • (c) 编写一段子程序以优美格式打印 的因数分解。最令人满意的是指数出现在指数位置;但是,如果这不可能,则将(比如说)的因数分解打印成

    (为了便于阅读,不打印等于 ​ 的指数)

见代码部分。 的质因数个数至多有 个。

代码-分解质因数

public class PrimeSplit {
    private int M;
    private List<Integer> ls;

    public PrimeSplit(int max) {
        M = (int) (Math.sqrt(max) + 1);
        boolean[] p = new boolean[M];
        ls = new ArrayList<>();
        Arrays.fill(p, true);
        for (int i = 2; i < M; i++) {
            if(p[i]) ls.add(i);
            for(int x: ls){
                if(x * i >= M) break;
                p[x * i] = false;
                if(i % x == 0) break;
            }
        }
    }
    public List<int[]> split(int n){
        List<int[]> res = new ArrayList<>();
        for (int x: ls) {
            if(x * x > n) break;
            int l = 0;
            while(n % x == 0){
                n /= x;
                l++;
            }
            if(l > 0) res.add(new int[]{x, l});
        }
        if(n > 1) res.add(new int[]{n, 1});
        return res;
    }
    public static void main(String[] args){
        int M = 1_000_030;
        PrimeSplit ps = new PrimeSplit(M);
        StringBuffer sb = new StringBuffer();
        for (int i = 1_000_000; i <= M; i++) {
            List<int[]> split = ps.split(i);
            sb.append(i);
            sb.append('=');
            boolean f = false;
            for (int[] x: split){
                if(f) sb.append('*');
                sb.append(x[0]);
                if(x[1] > 1){
                    sb.append('^');
                    sb.append(x[1]);
                }
                f = true;
            }
            System.out.println(sb);
            sb.setLength(0);
        }
    }
}

伯努利数

​ 前面手撕了部分自然数幂级求和公式,没找出明显规律,心想着不应该啊,然后去网上搜了搜,真被我发现了现成的结论,即伯努利数。

制作表格

得到伯努利数

​ 观察通项公式的系数,将其相加总是得到 ,事实上将 代入即可。因此我们有,消去 提出项,即有。以计算为例

​ 也可以考虑将展开,将替换为伯努利数,也能得到上述公式。伯努利数的性质和应用远不止这一点,而且还有很多没弄明白。伯努利数虽然可以计算出来,但本身没啥规律,或者是规律不够明显?

代码-伯努利数

Java
public BigInteger[][] bernoulli(int n){
    //包含分子分母各两项
    BigInteger[][] b = new BigInteger[n + 1][2];
    b[0] = new BigInteger[]{BigInteger.ONE, BigInteger.ONE};
    BigInteger[] f = new BigInteger[n + 2];
    Arrays.fill(f, BigInteger.ONE);
    for (int i = 1; i <= n; i++) {
        for (int j = i; j > 0; j--) {
            //C(i, j),也即C(i, i - j)
            f[j] = f[j].add(f[j - 1]);
        }
        b[i] = new BigInteger[]{BigInteger.ZERO, BigInteger.ONE};
        //根据已有结论:大于1的奇数项为0.可进行剪枝
        if(i > 1 && i % 2 == 1) continue;
        for (int j = 0; j < i; j++) {
            if(j > 1 && j % 2 == 1) continue;
            sub(b[i], b[j], f[j]);
        }
        gcd(b[i], i + 1);
    }
    return b;
}

private void gcd(BigInteger[] t, int i) {
    //gcd法约分
    t[1] = t[1].multiply(BigInteger.valueOf(i));
    BigInteger a = t[1], b = t[0].abs();
    while(b.compareTo(BigInteger.ZERO) > 0){
        BigInteger tp = a.mod(b);
        a = b;
        b = tp;
    }
    t[0] = t[0].divide(a);
    t[1] = t[1].divide(a);
}

public void sub(BigInteger[] a, BigInteger[] b, BigInteger mul){
    //通分
    a[0] = a[0].multiply(b[1]).subtract(b[0].multiply(a[1]).multiply(mul));
    a[1] = a[1].multiply(b[1]);
}

第八章 同余式

习题8.1

​ 假设 .

  • (a) 验证 .
  • (b) 验证 ​.

(a)

(b)

习题8.2

​ 假设 . 证明 .

,代入,即得

习题8.3

​ 求下述同余式的所有不同余解。

  • (a)
  • (b)
  • (c)
  • (d)
  • (e)

(a)

(b) 无解

(c)

(d)

(e) 无解

习题8.4

​ 证明下述整除性试验结果.

  • (a) 数 被 4 整除但且仅当它的末尾两位数被 4 整除。
  • (b) 数 ​ 被 8整除但且仅当它的末尾三位数被 8 整除。
  • (c) 数 ​ 被 3 整除但且仅当它的各位数字之和被 3 整除。
  • (d) 数 ​ 被 9 整除但且仅当它的各位数字之和被 9 整除。
  • (e) 数 被 11 整除但且仅当它的各位数字交错和被 11 整除。(如果 ,则交错和值交替加、减​)

(a)

(b)

(c)

(d)

(e)

习题8.5

​ 求下述线性同余式的所有不同余解。

  • (a)
  • (b)
  • (c)

(a)
(b) 无解
(c)

习题8.6

​ 确定下述同余式的不同余解的个数。无需求出解。

  • (a)
  • (b)
  • (c)

(a) ,无解
(b) ,有个解
(c) ,无解

习题8.7

​ 编写程序解同余式 . (如果不整除 c, 则输出出错信息和 的值)测试程序,求出习题8.6中同余式的所有解。

见代码部分

习题8.8

​ 编写程序,输入正整数 和 整系数多项式 ,输出同余式 的所有解。(无需细想,只需让 分别取 ,看看哪些值是解。)取多项式

对下述每个

通过解同余式 来测试程序。

见代码部分

习题8.9

​ (a) 同余式

有多少个解?有四个解嘛?还是少于四个解?

​ (b) 考察同余式 ,当 时它有几个解?注意它的解多余两个。为什么这个结果与模 多项式根定理(定理 8.2)矛盾?

(a) 使用习题8.8的程序验证,得两个解。事实上原式,而 不是 的平方剩余。
(b) 答:四个解。8 不是素数。

习题8.10

​ 设 为不同素数。同余式

最多可能有多少个解?这里我们照样只关心模 不同余的解。

答:4 个。,最多各两个解,进而两两组合解同余式,最多可得四个解。

代码-一元一次同余方程

Java
public Pair<Boolean, List<Integer>> remainder(int a, int c, int m){
    //欧几里得扩展法
    int[] g = _gcd(a, m);
    List<Integer> ls = new ArrayList<>();
    if(c % g[2] != 0){
        ls.add(g[2]);
        return new Pair<>(false, ls);
    }
    c = c * g[0] / g[2];
    for (int i = 0; i < g[2]; i++) {
        ls.add(c);
        c = (c + m / g[2]) % m;
    }
    return new Pair<>(true, ls);
}

代码-整系数多项式同余方程

Java
public List<Integer> remainder(int[] F, int m){
    List<Integer> ls = new ArrayList<>();
    for (int i = 0; i < m; i++) {
        int x = 1;
        int M = 0;
        for (int f : F) {
            M = (M + f * x) % m;
            x = x * i % m;
        }
        if(M == 0) ls.add(i);
    }
    return ls;
}

其他

  1. 数论概论第一部分
  2. 数论概论第二部分
  3. 数论概论第三部分
  4. 数论概论第五部分
  5. 数论概论第六部分
评论 (3)