虽然题目不难,但背后蕴含的考点还是很有意思的。
本题的核心考点是唯一分解定理。
此考点曾在NOIP中涉及,非常重要!!!
例如 NOIP2009 Hankson的趣味题
唯一分解定理:设 pi 表示第 i 个质数,那么对于任意正整数N,都有唯一的一组 a1,a2,a3…an ,使得
N=p1a1×p2a2×p3a3×⋯×pnan
其中 ai 可以等于0。
用白话文说:任何数都可以表示为他的质因数们的若干次幂的乘积,而幂指数序列是确定的。
推论:对于 ∀x,y ,其中
x=p1a1×p2a2×p3a3×⋯×pnan
y=p1b1×p2b2×p3b3×⋯×pnbn
则
gcd(x,y)=p1min(a1,b1)×p2min(a2,b2)×p3min(a3,b3)×⋯×pnmin(an,bn)
lcm(x,y)=p1max(a1,b1)×p2max(a2,b2)×p3max(a3,b3)×⋯×pnmax(an,bn)
回到本题,给定整数 n ,求有多少对 x,y ,满足 lcm(x,y)=n 。
对 n 分解质因数,得到 n 的唯一分解序列 S={a1,a2,a3,…,an} 。
对于序列中的每一个元素 ai ,要求 x,y 的分解序列中的对应元素 xi,yi 更大的那个与 ai 相等,另一个可以在 [0,ai−1] 中任取。
当 xi=ai 时, yi∈[0,ai−1] ,共 ai 种方法;
当 yi=ai 时, xi∈[0,ai−1] ,共 ai 种方法。
根据加法原理,应有 di=2×ai 种方法。
然而,刚刚的计算中, {xi=aiyi=ai 的情况被算了两次,因此要减1。
对于分解序列中的其他元素,根据乘法原理,各个质因数直接的方法互不干涉,最终的答案应当是各 di 相乘的积
i=1∏ndi
最后是时间复杂度分析。
计算的瓶颈在于分解质因数,如果使用Pollard_Rho进行分解,时间复杂度为 O(n) ,非常小的一个数;然而如果用暴力分解质因数,时间复杂度为 O(n) ,实际测试中可以通过本题。
实际上,在许多题目中,如果 n 在longlong范围内且没有多组数据, O(n) 的时间复杂度是很难TLE的。
所以本题就轻松愉快地解决啦!
总结:
-
唯一分解定理的内容及其推论,务必牢记
-
如果组成问题的各个“位”之间相互独立,可以考虑把待求解的问题“按位分解”,这种思想不仅在数论题中十分重要,在动态规划中也经常出现。
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#define re register
typedef long long ll;
using namespace std;
ll n,cnt,ans = 1;
int main(){
cin>>n;
for(re int i = 2; i < sqrt(n); ++i){
cnt = 0;
while(n%i==0){
++cnt;
n /= i;
}
if(cnt) ans *= (cnt<<1)+1;
}
if(n>1) ans *= 3;
cout<<ans<<endl;
return 0;
}