题意:求有多少对数对(i,j)满足lcm(i,j) = n,1<=i<=j, 1<=n<=1e14。
分析:根据整数的唯一分解定理,n可以分解为(p1^e1)*(p2^e2)*(p3^e3)*...*(pn^en)。其中pi是每个不同的素因子。
同样可将 i 和 j 分解为(a1^c1)*(a2^c2)^(a3^c3)...(an^cn) 和 (b1^d1)*(b2^d2)*(b3^d3)*...(bn^dn)。
因为lcm(i,j) = n。所以对任意 i,都有max(ci,di)= ei ,0 <= min(ci,di) <= ei,所以对n的每个素因子,都有2*(ei+1)-1种情况(减1是因为ci=di=ei的情况被算了2次)。
所有的可能 t 就是 (2ei+1)之积。这是有序对的数量,求无序对的时候 将 (t+1)/2,加1是因为(n,n)的情况本身只有一种可能。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn =1e7+5; const int INF =0x3f3f3f3f; bool notprime[maxn<<1]; vector<int> prime; //prime[0] 表示当前范围内有多少素数,prime[i] 表示第i个素数是多少 void pre() { memset(notprime,0,sizeof(notprime)); notprime[0] = notprime[1] = true; for(int i=2;i<maxn;++i){ if(!notprime[i]) prime.push_back(i); for(int j=0 ; j<prime.size() && prime[j] <= maxn / i ;++j){ notprime[prime[j]*i] = true; if(i%prime[j]==0) break; } } } LL getFactor(LL n) { LL tmp = n , res=1; for(int i=0;i<prime.size() && prime[i]*prime[i]<=tmp;++i){ int cnt =0; while(tmp%prime[i]==0){ cnt++; tmp/=prime[i]; } res *=(2*cnt +1 ); } if(tmp>1) res*= 3; res++; res>>=1; return res; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif pre(); int T,N,u,v,tmp,cas=1; scanf("%d",&T); while(T--){ LL n; scanf("%lld",&n); LL res= getFactor(n); printf("Case %d: %lld ",cas++,res); } return 0; }