CH 3101 - 阶乘分解 - [埃筛]

Posted dilthey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CH 3101 - 阶乘分解 - [埃筛]相关的知识,希望对你有一定的参考价值。

题目链接:传送门

 

题解:

$(1e6)!$ 这种数字,表示都表示不出来,想直接 $O(sqrt{N})$ 分解质因数这种事情就不要想了。

考虑 $N!$ 的特殊性,这个数字的所有可能包含的质因子,就是 $1 sim N$ 这些数所包含的质因子。因此,只需要考虑 $1 sim N$ 这每个数字的质因子即可。

那么,不妨筛出属于 $1 sim N$ 范围内的所有质数,对于每一个质数 $p$,$1 sim N$ 中显然有 $lfloor N/p floor$ 个能够被 $p$ 整除的数字,也就是说 $N!$ 的质因子中,可以确定至少有这么 $lfloor N/p floor$ 个 $p$。换句话说,产生了 $lfloor N/p floor$ 的贡献。

然后,我们进一步考虑,$lfloor N/p floor$ 个能够被 $p$ 整除的数字中,显然还有 $lfloor N/{p^2} floor$ 个能够被 $p^2$ 整除的数字,这些数字产生进一步产生贡献 $lfloor N/{p^2} floor$,往后依次类推 $lfloor N/{p^3} floor, lfloor N/{p^4} floor, cdots$。

 

AC代码:

#include<bits/stdc++.h>
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
int n;

const int MAX=1e6;
bool noprm[MAX+3];
vector<int> prm;
void Erato(int n)
{
    noprm[0]=noprm[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(noprm[i]) continue;
        prm.pb(i);
        for(int j=i;j<=n/i;j++) noprm[i*j]=1;
    }
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    cin>>n;
    Erato(n);
    for(auto p:prm)
    {
        ll cnt=0;
        for(ll x=p;x<=n;x*=p) cnt+=n/x;
        if(cnt>0) cout<<p<< <<cnt<<
;
    }
}

 

以上是关于CH 3101 - 阶乘分解 - [埃筛]的主要内容,如果未能解决你的问题,请参考以下文章

NYOJ 题目56 阶乘式因式分解

阶乘约数——蓝桥杯python组国赛题(C++唯一分解定理)

组合数(阶乘数质因子分解)

ACM阶乘因式分解

AcWing 197. 阶乘分解 质因数分解

197. 阶乘分解数论