【 阶乘分解】(素数)

题目:

给定整数 N ,试把阶乘 N! 分解质因数,按照算术基本定理的形式输出分解结果中的 pipi 和 cici 即可。

输入格式

一个整数N。

输出格式

N! 分解质因数后的结果,共若干行,每行一对pi,cipi,ci,表示含有pciipici项。按照pipi从小到大的顺序输出。

数据范围

1≤N≤1061≤N≤106

输入样例:

5

输出样例:

2 3
3 1
5 1

样例解释

5!=120=23∗3∗5

 

解题报告:显然直接暴力去求解n!,在进行质数分解,和分别求解1-n中的每个数分别进行质数分解的时间复杂度都非常的大,显然不是很合适。可以知道n!的每个质因子都在1-n之间,先进行一下1-n的质因子筛选,然后去考虑n!中一共含有多少个素因子p。

n!中质因子p的个数为:[n/p]+[n/p^2]+[n/p^3]+……+n[p^k];

可能看到这个式子在各种题解都是直接说可以求得,但是为什么呢,思考了好久,其实之前咱们去求解n!分别去枚举每个数的质因子分解是按照列的方式去进行的,而上述公式则是按照行的方式去求解,虽然最后的结果是一样的,但是思考方式是不同的,比如:

求解8!中2的数目:

按照列的方式去求解: 2   1

                                     4    2

                                     6    1

                                     8    3

最后是1+2+1+3=7;

按照行的方式去求解: 1 2 3 4 5  6 7 8

                                        1    1     1    1  (2^1)

                                              1           1    (2^2)

                                                           1    (2^3)

最后是4+2+1=7;

 

可能还是对于这个求解方式还有一定的思考空间,慢慢思考再来补齐吧!

 

附上普遍ac代码:

#include
using namespace std;
typedef long long ll;

const int maxn=1e6+1000;
int prime[maxn];
bool vis[maxn];
int cnt;

void db_Onion()
{
	cnt=0;
	vis[0]=vis[1]=1;
	for(int i=2;i>=1;
	}
	return res;
}
int main()
{
	db_Onion();
	ll n;
	cin>>n;
	for(ll i=2;i<=n;i++)
	{
		if(!vis[i])
		{
			ll ans=0;
			cout<

 

你可能感兴趣的:(acm训练,数论)