题目描述
分析
这道题的题意是有点绕的,这道题就是求解X所有的因子排个序,要求序列严格递增,且前一项都可以整除后一项
对于每一个序列b都有唯一的序列a与之对应
因此只需要求出b序列有多少个就能求出有多少个a序列
b序列的数量只需要求对X进行素因子分解之后的结果进行排列即可
根据组合数学的知识可以得到答案
在这道题中数据范围比较大,需要找到一种效率更高的方法进行素因子分解
回顾线性筛,我们只需要再线性筛中预处理出每个数的最小因子
然后查表进行素因子分解即可
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = (1 << 20) + 10;
int prime[N], cnt;
int mink[N];
bool st[N];
void get_prime(int n);
ll fun(int n);
int main()
{
get_prime(N - 1);
int x;
while (~scanf("%d", &x))
{
int sum = 0;
int d[30], m[30];
int k = 0;
while (x > 1)
{
int p = mink[x];
d[k] = p, m[k] = 0, k++;
while (x % p == 0)
{
x /= p;
m[k - 1]++;
sum++;
}
}
ll res = fun(sum);
for (int i = 0; i < k; i++)
res /= fun(m[i]);
cout << sum << " " << res << endl;
}
return 0;
}
void get_prime(int n)
{
for (int i = 2; i <= n; i++)
{
if (!st[i])
{
mink[i] = i;
prime[cnt++] = i;
}
for (int j = 0; prime[j] * i <= n; j++)
{
int t = prime[j] * i;
st[t] = true;
mink[t] = prime[j];
if (i % prime[j] == 0)
break;
}
}
}
ll fun(int n)
{
ll res = 1;
for (int i = 1; i <= n; i++)
res *= i;
return res;
}