Pairs Forming LCM
题目大意:
给定 \(t\) 个数 \(n\),对于每一个 \(n\) 求最大公倍数等于 \(n\) 的数对有多少个
一种全新的求解 \(\gcd\) 和 \(lcm\) 的方法:
对 \(a\) ,\(b\) 两个数进行质因数分解,得到:$$a = p_1^{x_1} * P_2^{x_2} * P_3^{x_3} *P_4^{x_4} *P_5^{x_5} *... P_{n-1}^{x_{n-1}} * p_n^{x_n}$$
\[b = p_1^{y_1} * P_2^{y_2} * P_3^{y_3} *P_4^{y_4} *P_5^{y_5} *... P_{n-1}^{y_{n-1}} * p_n^{y_n}
\]
\[\gcd(a,b) = p_1^{\min(x_1,y_1)} * p_2^{\min(x_2,y_2)} *p_3^{\min(x_3,y_3)}*...*p_n^{\min(x_n,y_n)}
\]
\[lcm(a,b) = p_1^{\max(x_1,y_1)} * p_2^{\max(x_2,y_2)} *p_3^{\max(x_3,y_3)}*...*p_n^{\max(x_n,y_n)}
\]
思路如下:
先对 \(n\) 素因子分解,得到,
\[n = p_1^{e_1} * P_2^{e_2} * P_3^{e_3} *P_4^{e_4} *P_5^{e_5} *... P_{n-1}^{x_{n-1}} * p_n^{x_n}
\]
当 \(lcm(a,b)==n\) 时,\(\max(x_1,y_1)==e_1,\max(x_2,y_2)==e_2,…\max(x_n,y_n)==e_n\)
当 \(a_i == e_i\) 时,\(b_i\) 可取 \([0, ei]\) 中的所有数 ,有 \(e_i+1\) 种情况,\(b_i==e_i\) 时同理。
那么就有 \(2(e_i+1)\) 种取法,但是当 \(a_i = b_i = e_i\) 时有重复,所以取法数为
\[2(ei+1)-1=2*ei+1
\]
除了 \((n, n)\) 所有的情况都出现了两次 那么满足 \(a<=b\) 的有 \((2*ei + 1)) / 2 + 1\) 个
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=1e7+5;
const int NN=1e6;
unsigned int prime[NN],cnt; //prime[N]会MLE
bool vis[N];
void is_prime()
{
cnt=0;
memset(vis,0,sizeof(vis));
for(int i=2;i<N;i++)
{
if(!vis[i])
{
prime[cnt++]=i;
for(int j=i+i;j<N;j+=i)
{
vis[j]=1;
}
}
}
}
int main()
{
is_prime();
int t;
cin>>t;
for(int kase=1;kase<=t;kase++)
{
LL n;
cin>>n;
int ans=1;
for(int i=0;i<cnt&&prime[i]*prime[i]<=n;i++)
{
if(n%prime[i]==0)
{
int e=0;
while(n%prime[i]==0)
{
n/=prime[i];
e++;
}
ans*=(2*e+1);
}
}
if(n>1)
ans*=(2*1+1);
printf("Case %d: %d\n",kase,(ans+1)/2);
}
}