当前位置:首页 > 技术 > 正文内容

唯一分解定理及其在约数计算中的应用

访客 技术 2026年8月22日 1

一、唯一分解定理基础

任意大于1的正整数均可唯一表示为若干不同质数幂的乘积:

唯一分解公式

其中 p₁, p₂, ..., pₘ 为互异质数,k₁, k₂, ..., kₘ 为其对应指数。该定理为整数结构分析提供了理论基础。

1.1 质因数分解实现

分解步骤:

  1. 从最小质数2开始试除目标数 n
  2. 若可整除则持续除尽并记录指数
  3. 递增试除因子直至 i ≤ √n
  4. 若最终 n > 1 则其本身为质因子
import java.util.*;

public class PrimeFactorization {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        List<int[]> factors = new ArrayList<>();
        
        for (int i = 2; i * i <= num; i++) {
            if (num % i == 0) {
                int exp = 0;
                while (num % i == 0) {
                    exp++;
                    num /= i;
                }
                factors.add(new int[]{i, exp});
            }
        }
        if (num > 1) factors.add(new int[]{num, 1});
        
        factors.forEach(f -> System.out.println(f[0] + " " + f[1]));
    }
}

二、约数个数计算

2.1 公式原理

n = p₁ᵏ¹ × p₂ᵏ² × ... × pₘᵏᵐ,则约数个数为:

约数个数公式

2.2 阶乘约数个数计算

public class FactorialDivisors {
    public static void main(String[] args) {
        int n = 100;
        int[] primeExponents = new int[n + 1];
        
        // 统计每个质因子在n!中的总指数
        for (int i = 2; i <= n; i++) {
            int temp = i;
            for (int j = 2; j * j <= temp; j++) {
                while (temp % j == 0) {
                    primeExponents[j]++;
                    temp /= j;
                }
            }
            if (temp > 1) primeExponents[temp]++;
        }
        
        long divisorCount = 1;
        for (int exp : primeExponents) {
            if (exp > 0) divisorCount *= (exp + 1);
        }
        System.out.println(divisorCount);
    }
}

三、约数和计算

3.1 公式原理

约数和公式为各质因子等比数列和的乘积:

约数和公式

3.2 单数约数和计算

import java.util.Scanner;

public class SingleNumberDivisorSum {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int original = n;
        int[] exponents = new int[n + 1];
        
        // 质因数分解
        for (int i = 2; i * i <= n; i++) {
            while (n % i == 0) {
                exponents[i]++;
                n /= i;
            }
        }
        if (n > 1) exponents[n] = 1;
        
        // 计算约数个数
        long count = 1;
        for (int exp : exponents) {
            if (exp > 0) count *= (exp + 1);
        }
        
        // 计算约数和
        long sum = 1;
        for (int p = 2; p <= original; p++) {
            if (exponents[p] == 0) continue;
            long geometricSum = 0;
            long power = 1;
            for (int j = 0; j <= exponents[p]; j++) {
                geometricSum += power;
                power *= p;
            }
            sum *= geometricSum;
        }
        
        System.out.println(original + " 的约数个数:" + count);
        System.out.println(original + " 的约数和:" + sum);
    }
}

3.3 阶乘约数和计算

import java.math.BigInteger;

public class FactorialDivisorSum {
    public static void main(String[] args) {
        int n = 100;
        int[] exponents = new int[n + 1];
        
        // 统计质因子指数(同约数个数逻辑)
        for (int i = 2; i <= n; i++) {
            int temp = i;
            for (int j = 2; j * j <= temp; j++) {
                while (temp % j == 0) {
                    exponents[j]++;
                    temp /= j;
                }
            }
            if (temp > 1) exponents[temp]++;
        }
        
        // 约数个数计算
        long count = 1;
        for (int exp : exponents) {
            if (exp > 0) count *= (exp + 1);
        }
        
        // 约数和计算(使用BigInteger防溢出)
        BigInteger sum = BigInteger.ONE;
        for (int p = 2; p <= n; p++) {
            if (exponents[p] == 0) continue;
            
            BigInteger base = BigInteger.valueOf(p);
            BigInteger geoSum = BigInteger.ZERO;
            BigInteger current = BigInteger.ONE;
            for (int j = 0; j <= exponents[p]; j++) {
                geoSum = geoSum.add(current);
                current = current.multiply(base);
            }
            sum = sum.multiply(geoSum);
        }
        
        System.out.println("100! 的约数个数:" + count);
        System.out.println("100! 的约数和:" + sum);
    }
}

总结图示

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。