【Contest Hunter 3101】阶乘分解【数论,数学】

题目大意:

题目链接:http://contest-hunter.org:83/contest/0x30「数学知识」例题/3101 阶乘分解
n!n!分解质因数。


思路:

n1e6n\leq 1e6,肯定是不能直接乘出来再分解的。
那么可以将1到nn的每个数分解质因数再合起来吗?时间复杂度O(nn)O(n\sqrt{n}),依旧不现实。
考虑每一个质数pp,在1到nn中,很明显是有[pn][\frac{p}{n}][][]表示向下取整)个数字含有质因数pp,有[p2n][\frac{p^2}{n}]个数有质因数p2......p^2......pkn\frac{p^k}{n}个数含有质因数pkp^k
所以,n!n!中就有pknc[p][k]\sum_{p^k\leq n}c[p][k]pp
时间复杂度O(nlogn)O(nlogn)


代码:

#include <cstdio>
#define N 2000010
using namespace std;

int p[N],c[N],v[N],n,m;
long long k;

void prime()  //线性筛质数
{
	for (int i=2;i<=n;i++)
	{
		if (!v[i])
		{
			p[++m]=i;
			v[i]=i;
		}
		for (int j=1;j<=m;j++)
		{
			if (p[j]>v[i]||i*p[j]>n) break;
			v[i*p[j]]=p[j];
		}
	}
}

int main()
{
	scanf("%d",&n);
	prime();
	for (int i=1;i<=m;i++)
	{
		k=1;
		while (k*p[i]<=n)
		{
			k*=p[i];  
			c[i]+=n/k;  //记录个数
		}
	}
	for (int i=1;i<=m;i++)
	 printf("%d %d\n",p[i],c[i]);
	return 0;
}
原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998633.html