阶乘质因数分解

1n106, 唯一分解(质因数分解) n!,输出 pi,ci

阶乘分解 AcWing197

思路

前置知识:线性筛 (质数判定的算法4)。

显然 n! 的每个质因子都小于等于 n

因为 n!=n(n1)(n2)(n3)321,所以质数 pn! 出现的次数为 p1n 出现的次数。

对于 i=1,2,3n

对于 p:若有 p|i,则 p 出现次数+1

对于 p2:若有 p2|i,则 p 出现次数 +1,而不是 +2,因为其中一个 pp|i 时被统计了。

对于 p3:若有 p3|i,则 p 出现次数 +1,而不是 +3,因为其中一个 pp|i 时被统计了,另一个 pp2|i 时被统计了。

...

pn! 中出现的次数为 np+np2+np3++nplogpn=pknnpk

综上有以下步骤:

  • 线性筛求 1n 内的质数。O(n)
  • 遍历 1n 内的质数,找出质数pp|nO(π(n))=O(nlogn)
    • 对于质数 p,求出在 n! 中出现的次数。O(logn)

π(x) 是小于等于 x 的质数个数,约等于 nlogn

综上时间复杂度为 O(n+nlognlogn)=O(n)

代码实现

int n;
long long v[N];
::std::vector<int> ps;
int main() {
	scanf("%d", &n);

	/* 线性筛 */
	for(int i = 2; i <= n; i++)
	{
		if(!v[i])
			v[i] = i, ps.push_back(i);
		for(int j : ps)
			if(v[i] < j || j > n / i) break;
			else v[i * j] = j;
	}

	for(int i : ps)
	{
		ll p = i;
		int c = 0;
		while(p <= n)
		{
			c += n / p;
			p *= i;
		}
		printf("%d %d\n", i, c);
	}
	return 0;
}

本文作者:kuailedetongnian

本文链接:https://www.cnblogs.com/kuailedetongnian/p/18521395

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   kuailedetongnian  阅读(38)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起