zoukankan      html  css  js  c++  java
  • 【数论】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;
        }
    }
    

      

  • 相关阅读:
    网卡
    java调用函数参数的传递机制及java内存管理
    zookeeper安装遇到的问题
    tcp/ip,http,socket mysql底层技术原理
    前台页面
    权限模块设计及使用
    spring security学习,使用过程
    mybatis处理集合、循环、数组和in等语句的使用
    sql语句的一些学习
    java 实现获取当天,当周,当月,当季,当年的时间段
  • 原文地址:https://www.cnblogs.com/wxjor/p/6192732.html
Copyright © 2011-2022 走看看