大概题意是找出对于整数对(i,j),他们的lcm为n,这样的整数对有多少。
看了大牛博客才懂,假设lcm(X,Y)=M,分别分解X,Y,M
X=x1^a1*x2^a2...
Y=x1^b1*x2^b2..
M=x1^c1*x2^c2..
Y=x1^b1*x2^b2..
M=x1^c1*x2^c2..
因为是公倍数 所以质因数肯定要相同
那么max(a1,b1)=c1...max(a2,b2)=c2。
当b1=c1的时候a1的取法是(c1+1)种,a1=c1是b1取法也是(c1+1)种,但是有两个(c1,c1),所有对于每一个c1来说总的取法是(2*c1+1).
因为要求i<=j,所以最后结果去重一下,但是(n,n)只有一次,那么解就是(ans+1)/2。
本来想转载的,但是突然搜不到大牛的博客了...
另外最后这个结果在没有进行最后一步去重的话,和(n*n)的所有因子个数是一样的。没想明白,求路过大牛解释。
可以引申一下lcm(i,j)对数=(n*n)的因子个数。
#include"cstdio"
#include"cstring"
#include"cmath"
#include"cstdlib"
#include"algorithm"
#include"iostream"
#include"map"
#include"queue"
#define LL long long
using namespace std;
#define MAXN 10000007
bool mark[MAXN];
int ss[MAXN/10],sscnt;
void ssb()
{
sscnt=0;
memset(mark,false,sizeof(mark));
mark[0]=mark[1]=true;
for(int i=2; i<=MAXN; i++)
{
if(!mark[i])
{
for(int j=i+i; j<=MAXN; j+=i) mark[j]=true;
ss[sscnt++]=i;
}
}
return ;
}
LL solve(LL n)
{
LL ans=1;
for(int i=0;i<sscnt&&ss[i]*ss[i]<=n;i++)
{
int r=0;
while(n%ss[i]==0)
{
r++;
n=n/ss[i];
}
ans=ans*(2*r+1);
}
if(n>1)
ans=ans*3;
return (ans+1)/2;
}
int main()
{
int t;
scanf("%d",&t);
ssb();
int cas=1;
while(t--)
{
LL n;
scanf("%lld",&n);
LL ans=solve(n);
printf("Case %d: %lld\n",cas++,ans);
}
return 0;
}