AcWing 179.阶乘分解 题解

AcWing 197. 阶乘分解 题解

更好的阅读体验

题目描述

给定整数 N N N , 试把阶乘 N ! N! N! 分解质因数,按照算术基本定理的形式输出分解结果中的 p i p_i pi c i c_i ci即可

输入格式

一个整数 N N N

输出格式

N ! N! N! 分解质因数后的结果,共若干行,每行一对 p i , c i p_i,c_i pi,ci ,表示含有 p i c I p_i^{c_I} picI项。按照 p i p_i pi 从小到大的顺序输出

数据范围

3 ≤ N ≤ 1 0 6 3 \le N \le 10^6 3N106

题解

对于 N ! N! N! 的质因子,我们可以判断,最大的质因子不超过 N N N

证明:

通过算数基本定理

对于任意正整数有
x = p 1 α 1 ⋅ p 2 α 2 ⋅ p 3 α 3 … ⋅ p n α n x=p_1^{\alpha_1} · p_2^{\alpha_2}·p_3^{\alpha_3}\dots·p_n^{\alpha_n} x=p1α1p2α2p3α3pnαn
其中 P i P_i Pi x x x 的质因子

对于 1 1 1 ~ N N N 的每个整数都可以分解成如算数基本定理的形式

因此 N ! N! N! 的算数基本定理为前 N N N 个数的算术基本定理的乘积,其中不存在超过 N N N 的质因子

得证

因此我们只需要筛出 1 1 1~ N N N 的质数即可

首先利用线性筛筛出其中的质数

 public static void init(int n)
    {
        Arrays.fill(isPrime,true);
        for(int i=2;i<=n;i++)
        {
            if(isPrime[i])
                Primes[cnt++]=i;
            for(int j=0;j<cnt;j++)
            {
                int p=Primes[j];
                if(p*i>n)
                    break;
                isPrime[p*i]=false;
                if(i%p==0)
                    break;
            }
        }
    }

筛得质数后

我们计算每个质数的阶数

即计算 1 1 1 ~ N N N 中有多少个数有质数 p p p

易得有 N / P N/P N/P个数有质数p,这些数是p的倍数,因此这些数有因子 p p p

又根据 N / P 2 N/P^2 N/P2个数中含有因子 p 2 p^2 p2

依次类推,我们可以计算出当 N / P k N/P^k N/Pk时为0,即质数 P P P对应的最大阶数为 k k k

计算阶数的代码如下

 for(int i=0;i<cnt;i++)
        {
            int res=0;
            int p=Primes[i];
            int tmp=n;
            while(tmp>0)
            {
                res+=tmp/p;
                tmp/=p;
            }
            System.out.println(Primes[i]+" "+res);
        }

完整代码

import java.io.*;
import java.util.*;

public class Main{
    static int n;
    static final int N=(int)1e6+10;
    static boolean[] isPrime=new boolean[N];
    static int[] Primes=new int[N];
    static int cnt=0;
    public static void  init(int n)
    {
        Arrays.fill(isPrime,true);
        for(int i=2;i<=n;i++)
        {
            if(isPrime[i])
                Primes[cnt++]=i;
            for(int j=0;j<cnt;j++)
            {
                int p=Primes[j];
                if(p*i>n)
                    break;
                isPrime[p*i]=false;
                if(i%p==0)
                    break;
            }
        }
    }
    public static void main(String[] agrs) throws IOException
    {
        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
        n=Integer.parseInt(reader.readLine());
        init(n);
        for(int i=0;i<cnt;i++)
        {
            int res=0;
            int p=Primes[i];
            int tmp=n;
            while(tmp>0)
            {
                res+=tmp/p;
                tmp/=p;
            }
            System.out.println(Primes[i]+" "+res);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值