POJ 2992 Divisors

来源:互联网 发布:ios用什么数据库 编辑:程序博客网 时间:2024/05/22 13:51
Divisors
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 11810 Accepted: 3523

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 263 - 1.

Sample Input

5 16 310 4

Sample Output

2616

Source

CTU Open 2005

题意:求组合数C(k,n)的因子有多少个
很明显要用到唯一分解定理,不打表直接计算肯定超时,可以计算从n到n-k+1的各因子数之和减去1到n的因子之和,再按照唯一分解定理的公式即可,注意结果输出会爆int,要用到long long

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>#include<stack>#include<queue>#include<deque>#include<set>#include<map>#include<cmath>#include<vector>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int, int> PII;#define pi acos(-1.0)#define eps 1e-10#define pf printf#define sf scanf#define lson rt<<1,l,m#define rson rt<<1|1,m+1,r#define e tree[rt]#define _s second#define _f first#define all(x) (x).begin,(x).end#define mem(i,a) memset(i,a,sizeof i)#define for0(i,a) for(int (i)=0;(i)<(a);(i)++)#define for1(i,a) for(int (i)=1;(i)<=(a);(i)++)#define mi ((l+r)>>1)#define sqr(x) ((x)*(x))const int inf=0x3f3f3f3f;int p[432/2],m,n,n1[435],n2[435];bool vis[432];ll ans[435][300];void prime()//素数打表,O(n(log n)),O(n),O(n*sqrt(n))均可{    mem(vis,0);    p[0]=0;    for(int i=2;i<=432;i++)    {        if(!vis[i])p[++p[0]]=i;        for(int j=1;j<=p[0]&&(ll)i*p[j]<=432;j++)        {            vis[i*p[j]]=1;            if(!(i%p[j]))break;        }    }}void fenjie(int m,int num[])//唯一分解{    for(int i=1;i<=p[0]&&(ll)p[i]*p[i]<=m;i++)    {        while(!(m%p[i]))            num[p[i]]++,m/=p[i];    }    if(m>1)num[m]++;}void init()//打表计算所有结果{    for(int i=0;i<=431;i++)//防止出现n为0的情况        for(int j=0;j<=299;j++)            ans[i][j]=1;    for(int i=2;i<=432;i++)    {        mem(n1,0);        mem(n2,0);        for(int j=1;j<=i>>1;j++)        {            fenjie(i-j+1,n1);            fenjie(j,n2);            for(int k=1;k<=432;k++)                ans[i][j]*=(n1[k]-n2[k]+1);        }    }}int main(){    prime();    init();    while(~sf("%d%d",&m,&n))    {        n=min(n,m-n);        pf("%lld\n",ans[m][n]);    }    return 0;}