素数分解的唯一性:p1^x1*p2^x2...pn^xn(一个整数可唯一地分解为一些不同质因子的若干次方的乘积)

再根据乘法原理 因子个数为(x1+1)*(x2+1) + ... + (xn + 1)

例题:LightOJ - 1028 (计算因子个数)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>

using namespace std;
#define LL long long
#define ULL unsigned long long
#define MAX int(1e6+18)//求MAX范围内的素数 
const int N  = 1e6+11;
const int M  = 1e6+11;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;

//bool su[N+1]={1,1,0}; int prm[N+1],sz=0;
 
long long su[MAX],cnt;  
bool isprime[MAX];  
void prime()  
{  
    cnt=1;  
    memset(isprime,1,sizeof(isprime));//初始化认为所有数都为素数  
    isprime[0]=isprime[1]=0;//0和1不是素数  
    for(long long i=2;i<=MAX;i++)  
    {  
        if(isprime[i]) {
            su[cnt++]=i;//保存素数i  
        } 
        for(long long j=1;j<cnt&&su[j]*i<MAX;j++)  
        {  
            isprime[su[j]*i]=0;//筛掉小于等于i的素数和i的积构成的合数  
        }  
    }  
}  
//void init(){
//    for(int i=2;i<N;i++){
//        if(!su[i]) prm[sz++]=i;
//        for(int j=0;j<sz;j++){
//            int t=prm[j]*i;
//            if(t>N) break;
//            su[t]=1;
//            if(i%prm[j]==0) break;
//        }
//    }
//}
LL solve(LL n){
    LL ans=1;
    for(int i=1;i<=cnt && su[i]*1ll*su[i]<=n;i++){
        if(n%su[i]==0){
            LL cntt=0;
            while(n%su[i]==0) {
                cntt++; n/=su[i];
            }
            
            ans=ans*(cntt+1);
        }
    }
    if(n!=1) ans<<=1;
//	printf("Ans = %d\n",ans); 
    return ans-1;
}
LL num(LL n){ //返回的是因子总数
    LL count=2;
    for(LL i=2;i<=sqrt(n);i++){
        if(n%i==0){
            if(i==sqrt(n) && n/i==i){ //如果两因子相同,则只加1
                 count++;   
            }
            else count+=2;
        }
    }
    return count;
}
int main(){
 //   init();
//    cout<<prm[0]<<prm[1]<<prm[2]<<endl;
    prime();
	int T ;scanf("%d",&T);
    int cas=1;
    while(T--){
        LL n;scanf("%lld",&n);
        printf("Case %d: %lld\n",cas++,solve(n));
    }
return 0;
}

换成输出num(n)-1,则超时。