首页 > 代码库 > 【数论】7041125因子数

【数论】7041125因子数

因子数    

 

7041125因子数

难度级别:B; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
试题描述

计算C(n,k)的因子的个数。

输入
有多行,每行包含两个正整数 n 和 k ,用一个空格分隔。
输出
多行,每行包含一个数,依次为各组输入数据对应的结果。
输入示例
5 1
6 3
10 4
输出示例
2
6
16
其他说明
数据范围:0 <= k <= n <= 431。

好长时间没有发题解了,今天刷完作业来一发……

    显然会炸Long Long,那么即使杨辉三角打表也不行。

    有一个公式为:C(N,M)=N!/M!(N-M)!

    将其做一个变形,就是C(N,M)=M+1~N连乘/(N-M)!

    注意,M+1乘到N与(N-M)!是不一样的。

    然后两个循环,将它们的质因子数记录到一个数组里。

    最后质因子指数加一再连乘,就得到答案了

代码如下:

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;int ks[1001];int N,M;void fj(int k){    int num=2;    while(k!=1){        if(k%num==0) k/=num,ks[num]++;        else num++;    }    return ;}void fj2(int k){    int num=2;    while(k!=1){        if(k%num==0) k/=num,ks[num]--;        else num++;    }    return ;}void Num(int N,int M){    for(int i=M+1;i<=N;i++) fj(i);    for(int i=1;i<=N-M;i++) fj2(i);    return ;}int main(){    while(scanf("%d%d",&N,&M)!=EOF){        memset(ks,0,sizeof(ks));        long long ans=1;        Num(N,M);        for(int i=1;i<=N;i++) ans*=(ks[i]+1);        cout<<ans<<endl;    }}

 

    如果有需要,我们也可以将程序用线性筛优化一下:

    (然而测评机太慢,给的运行时间与上一个一样……)

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;int ks[501];int map[501];int mark[501];int tot;int N,M;void work(int k,int p){    int num=1;    while(k!=1){        if(k%map[num]==0) k/=map[num],ks[map[num]]+=p;        else num++;    }    return ;}void eular(){	mark[1]=1;	for(int i=2;i<=500;i++){		if(!mark[i]) map[++tot]=i;		for(int j=1;j<=tot;j++){			if(i*map[j]>500) break;			mark[i*map[j]]=1;			if(i%map[j]==0) break;		}	}	return ;}void Num(int N,int M){    for(int i=M+1;i<=N;i++) work(i,1);    for(int i=1;i<=N-M;i++) work(i,-1);    return ;}int main(){	eular();    while(scanf("%d%d",&N,&M)!=EOF){        memset(ks,0,sizeof(ks));        long long ans=1;        Num(N,M);        for(int i=1;i<=N;i++) ans*=(ks[i]+1);        cout<<ans<<endl;    }}

  

【数论】7041125因子数