因式分解详解

考虑下面一个问题:

题面

题目描述

q次询问,每次将n质因数分解。

输入格式

第一行输入q,表示询问的次数。

第二至第q+1行,每行输入n,表示需要进行质因数分解的数。

输出格式

对于每次询问,将n分解质因数。

样例输入/输出

Input
3
12
2310
1000000007

Output
3=1×3
12=2^2×3
2310=2×3×5×7×11
1000000007=1000000007

数据范围

本题采用捆绑测试。
Subtask 1(10pts): t 10 , n 10000 t≤10, n≤10000
Subtask 2(20pts): t 100 , n 100000 t≤100, n≤100000
Subtask 3(40pts): t 100 , n 10 0 5 t≤100, n≤100^5
Subtask 4(30pts): t 500 , n 10 0 6 t≤500, n≤100^6

思路

Subtask 1

对于每次询问,直接从1枚举到n;如果枚举到的那个数为质数,那么就看n是否能被它整除;如果可以就不停地将n除以它,直到不能除(即n无法被它整除)为止。

时间复杂度: O( t n l o g n tnlogn )。
如果您现在还在用这种方法判素数,那么您就是萌新。

Subtask 2

容易发现根本就不需要判素数。原因如下:

如果这个数i能否拆分为一些数的乘积,且i能被n整除;那么i的所有因数就一定能被n整除。而之前已经枚举过了n的真因数(一个数的真因数为它的所有因数除去1和它自己),所以如果i不是质数那么n就一定不能被i整除。

去掉判素数的步骤即可。

时间复杂度: O( t n tn )。
如果您现在还在用这种方法判素数,那么您就是普及组能力以下的选手。

Subtask 3

注意到,我们只需要把i从1枚举到n的平方根(sqrt(n))。经过这复杂度为O(sqrt(n))的枚举过后,n必定是一个质数或是1.

原因显然,自己举几个例子就明白了。

时间复杂度: O( t s q r t ( n ) t sqrt(n) )。

如果您在用这种方法进行单个数的质因数分解,那么我就不能估计您的能力了;
如果您还在用这种方法进行多个数的质因数分解,那么您就是普及组选手 (话说我不是吗)

Subtask 4

这是质因数分解,所以我们只需要枚举质数能否被n整除。

那么,我们就可以提前用筛除sqrt(maxn)以内的质数,然后到时候只需要枚举这些质数能否被n整除就好啦。

当然,我们还要记住这句话 :我们只需要把i从枚举在n的平方根(sqrt(n))以内的质数。经过这复杂度远小于O(sqrt(n))的枚举过后,n必定是一个质数或是1。

注意到这一步是常数优化,但是往往这也是最重要的一步。

顺便提一句,这题中尽量要用欧拉筛,否则特别容易被卡常。

后记

2015.12.11: 学会质数
2016.4.23: 学会分解质因数
2019.3.12: 首次用C++分解质因数,用了Subtask 1的思路
2019.11.12 感谢 b 6 e 0 b6e0 大佬,帮我进化到了Subtask 2
2019.11.12 感谢 b e 60 be60 大佬,帮我进化到了Subtask 3
2020.4.13 感谢自己,帮我自己优化到了Subtask 4

还有,本蒟蒻觉得还可以优化……大家可以在评论区说一说哦! 超级优化,常数优化,剪枝都可以说哦!

PS: 不要跟我说打表,预处理这样的话。

求点赞关注啊……

原创文章 19 获赞 27 访问量 1946

猜你喜欢

转载自blog.csdn.net/Cherrt/article/details/105516430
今日推荐