题目大意
我们定义 f ( x ) = x 1 × ( x − 1 ) 2 × ( x − 2 ) 3 × ⋯ × 2 x − 1 × 1 x f(x)=x^1\times (x-1)^2\times (x-2)^3\times \cdots\times 2^{x-1}\times 1^x f(x)=x1×(x−1)2×(x−2)3×⋯×2x−1×1x。给定 n n n,求 f ( n ) f(n) f(n)的质因子分解形式。
求 f ( n ) f(n) f(n)的质因子分解形式,要求按照质因子大小排列,当指数为 1 1 1时应当忽略指数,具体格式要求参见样例。
样例输出
5
样例输出
f(5)=2^8*3^3*5
样例解释
f ( 5 ) = 2 4 × 3 3 × 4 2 × 5 1 = 2 8 × 3 3 × 5 f(5)=2^4\times 3^3\times 4^2\times 5^1=2^8\times 3^3\times 5 f(5)=24×33×42×51=28×33×5
数据范围
1 ≤ n ≤ 1 0 7 1\leq n\leq 10^7 1≤n≤107
题解
首先,我们可以用欧拉筛求出 1 0 7 10^7 107以内的质数 p i p_i pi以及,每个数的最小质因数 l t i lt_i lti。
我们用 t i t_i ti表示当前每个数未被算入答案的次数,用 c i c_i ci表示每个质数 i i i最终的次数。
我们从大到小枚举 i i i,对于每个 i i i,将 i i i分成 l t i lt_i lti和 i l t i \dfrac{i}{lt_i} ltii。 l t i lt_i lti是质数,所以可以将 i i i的次数贡献到 c l t i c_{lt_i} clti中;然后,将 t i l t i t_{\frac{i}{lt_i}} tltii的次数加上 i i i的次数即可。
最后,每个质数 i i i的 c i c_i ci即为这个质数的次数。
时间复杂度为 O ( n ) O(n) O(n)。
code
#include<bits/stdc++.h>
using namespace std;
const int N=1e7;
int n,fl=0,z[N+5],p[N+5],lt[N+5];
long long ans=0,c[N+5],t[N+5];
void init(){
for(int i=2;i<=N;i++){
if(!z[i]){
p[++p[0]]=i;lt[i]=i;
}
for(int j=1;j<=p[0]&&1ll*i*p[j]<=N;j++){
z[i*p[j]]=1;
lt[i*p[j]]=p[j];
if(i%p[j]==0) break;
}
}
}
int main()
{
// freopen("factorial.in","r",stdin);
// freopen("factorial.out","w",stdout);
init();
scanf("%d",&n);
for(int i=n;i>=2;i--){
t[i]+=n+1-i;
c[lt[i]]+=t[i];
t[i/lt[i]]+=t[i];
t[i]=0;
}
printf("f(%d)=",n);
for(int i=1;i<=p[0];i++){
if(c[p[i]]){
if(fl) printf("*");
else fl=1;
if(c[p[i]]==1) printf("%d",p[i]);
else printf("%d^%lld",p[i],c[p[i]]);
}
}
return 0;
}
文章描述了一个计算函数f(n)=x^1*(x-1)^2*...*2^(x-1)*1^x在给定n范围内的质因子分解的方法,利用欧拉筛求质数和最小质因数,时间复杂度为O(n)。
2938

被折叠的 条评论
为什么被折叠?



