题意:求解小于n的数a,b求有多少对a,b满足lcm(a,b)==n;
分析:由算数基本定理(素数筛)n=〖p1〗^e1×〖p2〗^e2×⋯×〖pk〗^ek,若lcm(a,b)==n;
则:a=〖p1〗^a1×〖p2〗^a2×⋯×〖pk〗^ak;
b=〖p1〗^b1×〖p2〗^b2×⋯×〖pk〗^bk;
其中ai,bi都小于等于ei;
如果两个数的lcm(a,b)==n则有ai取最大值bi随意和bi取最大值ai随意,这样计算过后,每一种情况都计算了两次,只有(n,n)这种情况计算了一次。所以根据ai的值一共情况为(2*ei+1)种,因为都是两次,只有(n,n)是一次,所以最后的结果是。
代码如下:
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <math.h>
#include <vector>
#include <utility>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
int k;
long long suv[100500];
const int N=10000100;
long long prime[N/10]={0};
int num_prime=0;
bool isNotPrime[N]={1,1};
void su(){
for(long i = 2 ; i < N ; i ++){
if(!isNotPrime[i])
prime[num_prime++]=i;
for(long j = 0 ; j < num_prime &&i*prime[j]<N ;j ++) {
isNotPrime[i * prime[j]] = 1;
if( !(i % prime[j]))break;
}
}
}
void prime_solve(long long n){
memset(suv,0,sizeof(suv));
for(long long i=0;i<num_prime&&prime[i]*prime[i]<=n;i++){
// cout<<prime[i]<<endl;
if(n%prime[i]==0){
while(n%prime[i]==0){
n/=prime[i];
suv[k]++;
}
k++;
}
}
if(n!=1)suv[k++]=1;
}//用这种分解方法比较快
int main(){
int t;
scanf("%d",&t);
int m=1;
su();
while(t--){
long long n;
scanf("%lld",&n);
k=0;
prime_solve(n);
long long sum=1;
for(int i=0;i<k;i++)
sum*=(2*suv[i]+1);
printf("Case %d: %lld\n",m++,(sum+1)/2);
}
return 0;
}