在算法竞赛中,我们有时需要对一些数据进行处理,比如求质因子及对应的个数,那我们该如何进行操作呢?
https://www.luogu.com.cn/problem/P2043https://www.luogu.com.cn/problem/P2043
题目描述
对 𝑁! 进行质因子分解。
输入格式
输入数据仅有一行包含一个正整数 𝑁,𝑁≤10000。
输出格式
输出数据包含若干行,每行两个正整数 𝑝,𝑎,中间用一个空格隔开。表示 𝑁! 包含 𝑎个质因子 𝑝,要求按 𝑝 的值从小到大输出。
输入输出样例
输入 #1
10
输出 #1
2 8 3 4 5 2 7 1
面对阶乘级的数据,如果我们先计算阶乘后的数据,那么数据将十分庞大,对其进行操作的话,在数据类型和时间复杂度上都会出现一些问题,这时,我们便想到可以对阶乘的每一个数字进行独立操作,用一个全局变量存储出现的个数。因此问题就被简化了。
同时有一个定律十分重要——唯一分解定理,即每一个正整数都能够唯一地表示为它的质因数的乘积。
同时,n中最多只包含一个大于的因子,用反证法可以轻松得到这个结论。
因此我们可以得到如下代码:
void decompose(int x)
{
for(int i = 2; i * i <= x; i ++)
{
while(x % i == 0)
{
cnt[i] ++;
x /= i;
}
}
if(x)
cnt[x] ++;
}
我们从2开始,一直枚举到,如果当前数可以被i整除,就将i的个数除尽,这样一来就不存在被合数整除的情况了,然后如果依然没有除尽,则说明剩下的数也是质数,对应加上即可。
附上完整代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int n;
int cnt[N];
void decompose(int x)
{
for(int i = 2; i * i <= x; i ++)
{
while(x % i == 0)
{
cnt[i] ++;
x /= i;
}
}
if(x)
cnt[x] ++;
}
int main()
{
cin >> n;
for(int i = 2; i <= n; i ++)
decompose(i);
for(int i = 2; i <= n; i ++)
if(cnt[i])
cout << i << " " << cnt[i] << endl;
}