当前位置: 首页 > news >正文

【勒让德公式】欧拉筛-阶乘分解

阶乘分解题解

题目传送门

197. 阶乘分解

一、题目描述

给定整数N,将阶乘N!分解质因数,按照算术基本定理的形式输出分解结果中的质因数pᵢ和对应的指数cᵢ。

二、题目分析

  1. 需要将N!表示为质数的幂次乘积形式
  2. 关键在于高效计算每个质数在N!中的出现次数
  3. 需要先找出所有≤N的质数

三、解题思路

  1. 使用欧拉筛法预处理所有≤N的质数
  2. 对于每个质数p,计算在N!中的次数:
    • 计算⌊N/p⌋ + ⌊N/p²⌋ + ⌊N/p³⌋ + … 直到pᵏ > N
  3. 输出所有质数及其对应的次数

四、算法讲解

欧拉筛法(线性筛)

  • 原理:每个合数只被它的最小质因数筛掉
  • 时间复杂度:O(n)
  • 实现步骤
    1. 遍历2到N的每个数i
    2. 如果i未被标记,则是质数,加入质数表
    3. 用当前数i与已知质数相乘标记合数
    4. 当i能被质数整除时停止标记

阶乘质因数分解

  • 勒让德公式:计算质数p在N!中的次数为:
    ∑⌊N/pᵏ⌋ (k=1,2,…直到pᵏ>N)
  • 例子:计算5!中2的指数
    ⌊5/2⌋=2, ⌊5/4⌋=1 → 2+1=3

五、代码实现

#include <bits/stdc++.h>
using namespace std;
// #define int long long
const int N = 1e6 + 10;
int prime[N], cnt;  // 质数表和计数器
int st[N];          // 标记是否为合数
int n;

// 欧拉筛法预处理质数
void init(int n)
{
    for (int i = 2; i <= n; i ++)
    {
        if(!st[i])  // i是质数
            prime[cnt ++] = i;  // 加入质数表
        // 用当前数和质数表中的数标记合数
        for (int j = 0; prime[j] * i <= n; j ++)
        {
            st[i * prime[j]] = 1;  // 标记合数
            if(i % prime[j] == 0) break;  // 保证每个合数只被最小质因数筛掉
        }
    }
}

void solve()
{
    cin >> n;
    init(n);  // 预处理≤n的所有质数
    
    // 对每个质数计算在n!中的次数
    for (int i = 0; i < cnt; i ++)
    {
        int p = prime[i];  // 当前质数
        int s = 0;         // 计数器
        
        // 计算p在n!中的次数:n/p + n/p² + n/p³ + ...
        for (int j = n; j ; j /= p)
        {
            s += j / p;
        }
        cout << p << " " << s << "\n";  // 输出质数和次数
    }
}

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    solve();
    return 0;
}

六、重点细节

  1. 筛法范围:只需要筛到N,因为N!的质因数不会超过N
  2. 次数计算:使用勒让德公式,通过不断除以p来计算总次数
  3. 效率优化:欧拉筛法保证质数预处理高效,次数计算也是对数级别
  4. 边界处理:N≥3,无需处理特殊情况

七、复杂度分析

  • 时间复杂度
    • 预处理质数:O(n)
    • 计算每个质数的次数:O(cnt * logₚN) ≈ O(n/lnn * lnn) = O(n)
  • 空间复杂度:O(n),用于存储质数表和标记数组

八、总结

本题通过欧拉筛法高效预处理质数,再应用勒让德公式计算每个质数在阶乘中的次数,实现了对阶乘的质因数分解。算法结合了数论中的筛法和阶乘性质,在O(n)时间复杂度内解决问题,是质因数分解的经典应用。

相关文章:

  • 【硬件开发技巧】如何通过元器件丝印反查型号
  • vector模拟实现(2)
  • 蓝桥杯2024年第十五届省赛真题-拔河
  • 专栏:区块链入门到放弃查看目录
  • el-tabs添加按钮增加点击禁止样式
  • ubuntu 配置固定ip
  • getline(cin, )
  • Qt音频输出:QAudioOutput详解与示例
  • 玄机-apache日志分析
  • PDF预览-搜索并高亮文本
  • 基于OpenXLSX库创建的CAPL中可用的解析xlsx文件的DLL
  • traefik k3s配置
  • MongoDB基础知识
  • 页游(弹弹堂)刷怪脚本教程(一)---大漠插件制作颜色变化的字体字库(按键精灵)
  • Java项目之基于ssm的个性化旅游攻略定制系统(源码+文档)
  • http://noi.openjudge.cn/_2.5基本算法之搜索_1804:小游戏
  • 实验室预约|实验室预约小程序|基于Java+vue微信小程序的实验室预约管理系统设计与实现(源码+数据库+文档)
  • JMeter接口性能测试从入门到精通
  • FreeCAD傻瓜教程-钣金工作台SheetMetal的安装和简单使用
  • AIP-214 资源过期
  • php餐饮美食店网站源码 生成html/网站top排行榜
  • 报告格式范文/推广seo网站
  • 凡科建站公司/免费网站在线客服系统源码
  • 韩韩良品只做性价比网站下载/职业培训学校加盟合作
  • 翡翠原石网站首页怎么做/百度提交网站的入口地址
  • 网站改版影响/百度一下电脑版网页