Your task in this problem is to determine the number of divisors of Cnk. Just for fun -- or do you need any special reason for such a useful computation?
Input
The input consists of several instances. Each instance consists of a single line containing two integers n and k (0 ≤ k ≤ n ≤ 431), separated by a single space.
Output
For each instance, output a line containing exactly one integer -- the number of distinct divisors of Cnk. For the input instances, this number does not exceed 2 63 - 1.
Sample Input
5 1 6 3 10 4
Sample Output
2 6 16
题目大意:给你两个数,计算出这两个数的组合数之后的真因子个数,题目很简单,单数给出的数据太大,这就变成了一个比较难的题目了,并且这个题还卡你时间,一不小心就会超时,烦人得很,所以我们的办法就是打表,用一个二维数组,存放每一个数的阶乘的素数的个数,第一维放要求的这个数,第二维放这个数下面的素数,其值表示这个数的阶乘下面的所有(即从1到这个数)素数的个数,用分子上同一素数的幂减去分母上同一素数的幂,这样就能计算出来,并且时间不会超时。
代码如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;
typedef long long ll;
ll prime[500],isprime[500];
ll cnt=0;
ll dis[500][500];
ll vis[500];
void olashai()
{
for(ll i=2;i<=460;i++)
{
if(isprime[i]==0) prime[++cnt]=i;
for(ll j=1;j<=cnt&&prime[j]*i<440;j++)
{
isprime[prime[j]*i]=1;
if(i%prime[j]==0) break;
}
}
}
ll jisuan(ll x)
{
ll k=x,ans=0;
for(ll i=1;i<=cnt;i++)
{
dis[k][prime[i]]+=vis[prime[i]];
if(x%prime[i]==0)
{
while(x%prime[i]==0)
{
vis[prime[i]]+=1;
dis[k][prime[i]]+=1;
x/=prime[i];
}
}
}
}
int main()
{
ll n,m;
olashai();
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
for(ll i=1;i<=431;i++)
jisuan(i);
while(~scanf("%lld%lld",&n,&m))
{
ll ans=1;
for(ll i=1;i<cnt;i++)
{
ans*=((dis[n][prime[i]]-dis[m][prime[i]]-dis[n-m][prime[i]])+1);
// printf("%lld %lld %lld\n",dis[n][i],dis[m][i],dis[n-m][i]);
}
printf("%lld\n",ans);
}
return 0;
}
革命尚未成功,同志还需努力,加油!!!