计算不同“因子树”的个数
分解为两种计数模型:二叉树计数+可重复排列
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
#include<string.h>
#include<math.h>
#include<queue>
#include<map>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ll long long
using namespace std;
const ll maxm = 100000+10;
const ll maxn = 300;
ll n,num[maxn];
ll c[maxn][maxn];
vector<ll> prime;
bool not_prime[maxm];
void init(){
for(ll i=2;i<=maxm-5;i++){
if(!not_prime[i]) prime.push_back(i);
for(ll j=0;j<prime.size()&&i*prime[j]<=maxn-5;j++){
not_prime[i*prime[j]]=1;
if(!(i%prime[j])) break;
}
}
for(ll i=1;i<=100;i++){
for(int j=0;j<=i;j++){
if(i==j||j==0) c[i][j]=1;
else c[i][j]=c[i-1][j]+c[i-1][j-1];
}
}
}
ll solve(ll n){
ll cnt=0,sum=0,res=1;
memset(num,0,sizeof(num));
bool flag=false;
for(ll i=0;prime[i]*prime[i]<=n;i++){
if(n%prime[i]==0){
flag=true;
while(n%prime[i]==0) num[cnt]++,n/=prime[i];
sum+=num[cnt++];
}
}
if(!flag) return 1;
if(n!=1) num[cnt]=1,sum++;
res=c[2*(sum-1)][sum-1]/sum;
for(ll i=0;i<cnt;i++){
res*=c[sum][num[i]]; sum-=num[i];
}
return res;
}
int main(){
init();
while(scanf("%lld",&n)!=EOF){
printf("%lld\n",solve(n));
}
return 0;
}