ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

X的因子链(筛质数、分解质因数、组合计数)————《信息学奥赛一本通》 , POJ

2021-11-26 20:00:24  阅读:194  来源: 互联网

标签:int 质数 因子 POJ 奥赛 序列 长度 primes


X的因子链

输入正整数 X,求 X 的大于 1 的因子组成的满足任意前一项都能整除后一项的严格递增序列的最大长度,以及满足最大长度的序列的个数。

输入格式
输入包含多组数据,每组数据占一行,包含一个正整数表示 X。

输出格式
对于每组数据,输出序列的最大长度以及满足最大长度的序列的个数。

每个结果占一行。

数据范围
1≤X≤220
输入样例:
2
3
4
10
100
输出样例:
1 1
1 1
2 1
2 2
4 6

题解思路

由算数基本定理得
X一定可以拆分成多个质数的乘积,序列可以以一个质因数开头,每次乘以X的其中一个质因子,最后乘到X,
因为质数是X因子中已经不可再分的了,把X拆分成质数的乘积后,可以保证序列的长度最长,序列的最长长度就是质因子的个数
求序列的数量:
如果质因子乘的次序不同,序列也会不同,因为质因子可能会有重复,
因此可以用排列组合的知识(多重集合的排列问题),
序列的个数=用质因子个数的阶乘除以各个质因子重复出现次数的阶乘

比如 2 ∗ 2 ∗ 2 ∗ 3 ∗ 3 ∗ 4 = 288 2*2*2*3*3*4 = 288 2∗2∗2∗3∗3∗4=288, 质因子数量总共是6, 2有三个,3有两个,4有1个,因此序列的最长长度为6,序列的数量= 6!/(3!*2!)

在这里插入图片描述

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
/*

*/
const int N = (1<<20)+5;
typedef long long LL;

int primes[N],cnt;
bool st[N];
int min_fact[N];  //min_fact[i]存储i的最小质因数

void get_primes(int n)
{
    for(int i=2; i<=n; ++i){
        if(!st[i]){
            primes[cnt++] = i;
            min_fact[i] = i;
        }
        for(int j=0; primes[j]*i<=n; ++j)
        {
            st[primes[j]*i] = true;
            min_fact[primes[j]*i] = primes[j];
            
            if(i%primes[j] == 0) break;
        }
    }
}
int sum[N]; //记录每个质因子出现的次数
int main()
{
    get_primes(N-1);
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int k = 0, tot = 0;  //tot存储最大长度,k存储质因子数量
        while(n>1)
        {
            int p = min_fact[n];
            sum[k] = 0;
            while(n%p==0){
                sum[k]++;
                tot++;
                n/=p;
            }
            k++;
        }
        LL res = 1;
        for(int i=2; i<=tot; ++i)
            res *= i;
        for(int i=0; i<k; ++i){
            for(int j=1; j<=sum[i]; ++j){
                res /= j;
            }
        }
        printf("%d %lld\n",tot,res);
    }
    return 0;
}

标签:int,质数,因子,POJ,奥赛,序列,长度,primes
来源: https://blog.csdn.net/qq_26139541/article/details/121567429

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有