整数分解与筛法 X-factor Chain
题目描述
原题来自 POJ 3421
输入正整数 \(x\),求 \(x\) 的大于 \(1\) 的因子组成的满足任意前一项都能整除后一项的序列的最大长度,以及满足最大长度的序列的个数。
输入格式
多组数据,每组数据一行,包含一个正整数 \(x\)。
输出格式
对于每组数据,输出序列的最大长度以及满足最大长度的序列的个数。
样例
| Input复制 | Output复制 |
|---|---|
2 |
1 1 |
3 |
1 1 |
4 |
1 1 |
10 |
2 1 |
100 |
4 6 |
数据范围与提示
对于全部数据,\(1≤x≤2^{20}\)。
算法分析
仔细想一下,其实不难得出以下结论:
- 一个数可以分解成\(p_1^{e_1}p2^{e_2}...p_k^{e_k}\)的形式。
- 这个数的最大长度就是\(e_1+e_2+...+e_k\),我们令它为\(len\)。
- 个数就是\(\frac{len!}{e_1!e_2!...e_k!}\)。
有了以上结论,那么思路也出来了:
- 预处理出\(1!,2!,...,20!\),存在一个\(p\)数组里。
- 对于每个数,对它分解质因数,求出\(len和\frac{len!}{e_1!e_2!...e_k!}\)。
#include<bits/stdc++.h>
using namespace std;
long long n;
int k = 0;
long long sum = 0;
long long p[25];
long long v[1000005];
void jc(){//预处理阶乘
p[0] = 1;
for(int i = 1; i<=20; i++){
p[i] = p[i-1]*i;
}
}
void fj(long long x){//分解质因数
for(int i = 2; i*i<=x; i++){
if(x%i==0){
int cnt = 0;
while(x%i==0){
cnt++;
sum++;
x/=i;
}
v[++k] = cnt;
}
}
if(x>1){
v[++k] = 1;
sum++;
}
}
int main(){
jc();
while(cin>>n){//多组数据
if(n==1){
cout<<"0 1\n";
continue;
}
k = 0;
sum = 0;//重置
fj(n);
long long ans = p[sum];
for(int i = 1; i<=k; i++){
ans/=p[v[i]];
}
cout<<sum<<" "<<ans<<'\n';
}
return 0;
}

浙公网安备 33010602011771号