Divisors
Description
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 Source |
[Submit] [Go Back] [Status] [Discuss]
题意:求C(n,k)的因子个数。
题解:C(n,k)=n!/k!/(n-k)!,直接将所有阶乘的数分解出所有素因数然后统计一下
然后套用因数个数公式就好 (p1+1)*(p2+1)*(p3+1)*...*(pn+1)
题目很简单,然而卡时间,500*50*50都卡??
好吧,预处理一下就OK了。。。。。
定义dp[i][j]:表示i的阶乘里有几个素数j。
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<time.h>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<functional>
using namespace std;
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define maxn 50500
#define lowbit(x) (x&-x)
#define eps 1e-9
ll a[505]={1,1},b[500];
ll dp[450][450],cnt;
void init()
{
ll i,j;
for(i=2;i<=432;i++)
{
if(a[i])
continue;
b[++cnt]=i;
for(j=i*i;j<=432;j+=i)
a[j]=1;
}
for(i=2;i<=432;i++)
{
for(j=1;b[j]<=i && j<=cnt;j++)
{
ll tmp=i,res=0;
while(tmp)
tmp/=b[j],res+=tmp;
dp[i][b[j]]=res;
}
}
}
int main(void)
{
init();
ll i,x,y;
while(scanf("%lld%lld",&x,&y)!=EOF)
{
ll ans=1;
for(i=1;b[i]<=x && i<=cnt;i++)
{
ll tmp=dp[x][b[i]]-dp[y][b[i]]-dp[x-y][b[i]];
ans=ans*(tmp+1);
}
printf("%lld\n",ans);
}
return 0;
}