质因数分解
Posted znk161223
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了质因数分解相关的知识,希望对你有一定的参考价值。
??我们很容易发现,一个数最多只有一个大于(sqrt{n})的质因子。
证明:假设(exists{n}inmathbb{R},n)有两个大于(sqrt{n})的质因子,分别记为(p_1,p_2),
???则(ngeqslant p_1p_2),
???又(p_1,p_2>sqrt{n}),
???( herefore p_1p_2>n),矛盾,
???( herefore)一个数最多只有一个大于(sqrt{n})的质因子。
??所以我们只需要考虑(1~sqrt{n})之间的质因子,用他们来试除(n),若最终(n)仍不为(1),那么此时的n便是那个大于(sqrt{n})的质因子。
??大体的流程已经清楚,但是,在具体实现时的一些细节上我们仍然可以来优化它。
??试看下面这道例题。
例题:小凯的函数
??很显然,这一题就是要我们求出一个数的质因子个数。
up=sqrt(a);
ans=0;
//prime[]数组是用欧拉筛预处理出的质数
for(int i=1;prime[i]<=up;++i){
while(a%prime[i]==0){
a/=prime[i];
ans++;
}
}
if(a!=1) ans++;
??这样写看起来没有任何问题,然而提交之后你就会发现这样会超时,只能得到50分。
??那么,问题出在哪里?
??前面我们已经知道,一个数最多只有一个大于(sqrt{n})的质因子,所以我们只需要考虑(1~sqrt{n})之间的质因子。而每次试除成功后,(a)的值已然发生改变(为了方便叙述,我们将之记作(a'))。我们在接下来的试除过程中,只需考虑(1~sqrt{a'})的质因子,(sqrt{a'}~sqrt{a})的质因子就不用再考虑了。而如果我们按照上述写法,则仍然考虑了(sqrt{a'}~sqrt{a})这一部分质因子,引起超时。所以我们应当在每次(a)的值发生改变后,就相应地改变上界,减少时间的浪费。虽然这样时间复杂度仍然是(O(sqrt{n}))级别的,但是由于减少了冗余的试除,实际跑起来会快许多。
??代码如下。
up=sqrt(a);
for(register int i=1;prime[i]<=up;++i){
if(a%prime[i]==0){
while(a%prime[i]==0){
a/=prime[i];
++ans;
}
up=sqrt(a);
}
}
if(a!=1) ++ans;
以上是关于质因数分解的主要内容,如果未能解决你的问题,请参考以下文章