分析:首先可以发现n是一个long long类型的数,如果我们直接三重for循环枚举是绝对不可取的,现在我们考虑一个问题,假如存在x*y*z=n,且x和y以及z均不相同,那么对于这三个数对答案的贡献是多少呢?显然是3!,也就是6,假如存在两个数相同呢?那么贡献就是3,因为这取决于与其他两个数不同的那个数的位置。如果要是三个数均相同,那么答案显然就是1了。所以我们假如我们要枚举三重for循环i,j,k,那么也可以假定i<=j<=k,然后再判断三者之间有几个数是相同的来判断这三个数对答案的贡献。那么我们可以发现枚举两重for循环也是可以的,比如我们枚举i和j,如果n%(i*j)=0,说明存在k=n/i/j使得i*j*k=n成立,那么复杂度会明显减少,枚举第二重循环的时候需要注意我们可以令k等于j来得到k的下界,不然可能会重复记录,细节见代码即可,但是可以发现这样做复杂度还是有点偏高,所以我们来进行最后的优化,我们可以发现上述枚举的数都是n的因子,所以我们完全可以先用O(sqrt(n))的复杂度求出n的因子,然后我们直接对因子进行枚举即可。
答案为2430
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int N=1e5+10;
vector<long long>p;//存n的因子
int main()
{
long long n=2021041820210418;
for(long long i=1;i*i<=n;i++)
{
if(n%i!=0) continue;
p.push_back(i);
if(i*i!=n) p.push_back(n/i);
}
sort(p.begin(),p.end());
long long ans=0;
for(long long i=0;p[i]*p[i]*p[i]<=n;i++)
for(long long j=i;p[i]*p[j]*p[j]<=n;j++)
{
if(n%(p[i]*p[j])!=0) continue;//说明不存在k使得i*j*k=n
long long k=n/(p[i]*p[j]);
if(i==k) ans++;//三个数均相同
else if(i==j||j==k) ans+=3;//两个数相同
else ans+=6;//三个数均不相同
}
printf("%lld\n",ans);
return 0;
}