题目链接点击打开链接
题意: 给一个数x , 找出x 的因子 满足 后一个因子是第一个因子的倍数 的因子的最长长度 , 求改该长度的种类数
思路:求该数的所有质因子的 指数 和,并求出这些数的组合数 。定理: 总共有N个数, m种 , 每种数的个数分别为N1 , N2 , N3 。。。 Nm ,其组合数为N!/ (N1! *N2! * N3! *Nm!)
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <cstring>
typedef long long ll ;
using namespace std;
ll fac[21] ;
void Init()
{
fac[0] = 1 ;
for(int i = 1 ; i <= 20 ; i ++) // 计算阶乘
{
fac[i] = i * fac[i-1] ;
}
}
int main()
{
ll n ;
Init() ;
while(scanf("%lld" , &n) != EOF)
{
ll ans = 0 , base = 1 , cnt = 0 ;
for(int i = 2 ; i * i <= n ; i ++) //ans 为质因子的指数和 , base为不同种类数的阶乘积
{
if(n %i == 0)
{
cnt = 0 ;
while(n%i == 0)
{
cnt ++ ;
n/= i ;
}
ans += cnt ;
base *= fac[cnt] ;
}
}
if(n > 1) ans += 1 ; //注意+1
printf("%lld %lld\n" , ans , fac[ans]/base) ;
}
return 0;
}
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <cstring>
typedef long long ll ;
using namespace std;
const ll maxv = (1<<20) + 5 ;
ll prime[maxv] ;
bool is_prime[maxv] ;
ll fac[21] , len = 0 ;
void Init()
{
fac[0] = 1 ;
for(int i = 1 ; i <= 20 ; i ++) // 计算阶乘
{
fac[i] = i * fac[i-1] ;
}
}
void sieve()
{
for(ll i = 0 ; i < maxv ; i ++) is_prime[i] = true ;
prime[0] = prime[1] = false ;
for(ll i = 2 ; i < maxv ; i ++)
{
if(is_prime[i])
{
prime[len++] = i ;
for(ll j = i * i ; j < maxv ; j += i)
is_prime[j] = false ;
}
}
}
int main()
{
ll n ;
Init() ;
sieve() ;
while(scanf("%lld" , &n) != EOF)
{
if(is_prime[n]) printf("1 1\n") ;
else
{
long long ans = 0 , cnt = 0 , base = 1 ;
for(ll i = 0 ; i < len && prime[i] <= n && n != 1 ; i ++)
{
cnt = 0 ;
if(n % prime[i] == 0)
{
while(n % prime[i] == 0)
{
cnt ++ ;
n /= prime[i] ;
}
}
ans += cnt ;
base *= fac[cnt] ;
}
printf("%lld %lld\n" , ans , fac[ans]/base) ;
}
}
return 0;
}