【数论】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;
    }
}

  

时间: 2025-01-12 04:49:48

【数论】7041125因子数的相关文章

hdoj 1492 The number of divisors(约数) about Humble Numbers 【数论】【质因子分解 求和】

定理:一个正整数 n 可以用素因子唯一表示为 p1^r1 * p2^r2 * ... pk^rk (其中 pi 为素数) , 那么这个数的因子的个数就是,(r1+1)*(r2+1)*...*(rk+1). 理解:为什么是加1之后再相乘,因为一个数的的因子数至少为1和他自身,但因为r1,r2..可以为0,所以因子的个数为(r1+1)... 拓展一下: 定理1: 一个正整数 n 可以用素因子唯一表示为 p1^r1 * p2^r2 * ... pk^rk (其中 pi 为素数) , 那么这个数的因子的

CodeForces 577A Multiplication Table 质因子数

题目:click here 题意:看hint就懂了 分析:数论小题,在n0.5时间里求n的质因子数 #include <bits/stdc++.h> using namespace std; typedef long long ll; int n, x; ll ans; void solve() { ans = 0; for( int i=1; i*i<=x; i++ ) { if( i <= n ) { if( x%i == 0 && x/i <= n )

数论线性筛总结 (素数筛,欧拉函数筛,莫比乌斯函数筛,前n个数的约数个数筛)

线性筛 线性筛在数论中起着至关重要的作用,可以大大降低求解一些问题的时间复杂度,使用线性筛有个前提(除了素数筛)所求函数必须是数论上定义的积性函数,即对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b),在数论上就称它为积性函数,若a,b不互质也满足的话则称作完全积性函数,下面说明每个筛子是怎么筛的. 最基础的是素数筛,其它三个筛都是以素数筛为前提 素数筛 void get_prime() { int pnum = 0; for(int i = 2;

Trailing Loves (or L&#39;oeufs?) CodeForces - 1114C (数论)

大意: 求n!在b进制下末尾0的个数 等价于求n!中有多少因子b, 素数分解一下, 再对求出所有素数的最小因子数就好了 ll n, b; vector<pli> A, res; void factor(ll x) { int mx = sqrt(x+0.5); REP(i,2,mx) if (x%i==0) { int t = 0; while (x%i==0) x/=i,++t; A.pb(pli(i,t)); } if (x>1) A.pb(pli(x,1)); } int main

kuangbin带你飞---数论基础

又是几天过去,最近在刷数论基础和dp基础.kuangbin数论专题刷了差不多一大半吧.深深感jio到自己的菜.唉,温故而知新,所以决定在踩一遍坑点. Bi-shoe and Phi-shoe https://vjudge.net/problem/LightOJ-1370 题目大意:给出一些数字,对于每个数字找到一个欧拉函数值大于等于这个数的数,求找到的所有数的最小和. 分析:其实用欧拉筛打表欧拉函数值可以发现一个规律,质数的欧拉函数上升增加的速度远比其他数字快,所以此题只用找到第一个大于n的数即

「CodeForces-498C」Array and Operations(数论+网络流)

「CodeForces-498C」Array and Operations给定n个点和m个边集,每次操作可以将相连边的两个点值同时除以一个公约数,问最大操作次数 题意 给定一个长为$n$的数组,以及$m$对下标为$(a,b)$的点对,且满足下标a+b为奇数(即奇数点只与偶数点匹配),每次操作可以将同一组的两个数同时除以一个公约数,问最多能进行多少次操作. 解法 显然题目所给的是一个二分图. 对于每个质因数分开考虑.对于奇数点,向源点连接一个容量为该因子个数的边:对于偶数点,则向汇点建立一个容量为

物质的数论(物质的几何学)

美国的数学家和数学史权威莫里斯?克莱因教授说:“1930年以后[西方数学]的全部发展还留下来两个没有解决的大问题:去证明不加限制的经典分析与集合论的相容性,以及在[几何]严格直观的根基上去[重新]建立数学,或者去确定这种途径的限度.在这两个问题中,困难的根源都在于无穷集合和无限程序中所用到的无限(infinity).这个概念,即使对于希腊人也已经在无理数上造成了问题,而且他们在穷竭法中躲开它.从那以后,无限这个概念一直是争论的题目,并使外尔(Weyl)说道,数学是无限的科学.”([美]莫里斯?克

求连续子数组的最大和

一.题目: 这是一道考的烂的不能再烂的题目,但是依然有很多公司乐于将这样的题目作为笔试或面试题,足见其经典. 问题是这样的:一个整数数组中的元素有正有负,在该数组中找出一个连续子数组,要求该连续子数组中各元素的和最大,这个连续子数组便被称作最大连续子数组.比如数组{2,4,-7,5,2,-1,2,-4,3}的最大连续子数组为{5,2,-1,2},最大连续子数组的和为5+2-1+2=8. 二.解法: 解法一:暴力求解法 /* (1) 常规方法,时间复杂度O(n*n) (2) 先从第一个元素开始向后

NKOJ1236 a^b (数论定理的应用)

          a^b 对于任意两个正整数a,b(0<=a,b<10000)计算a b各位数字的和的各位数字的和的各位数字的和的各位数字的和. Input 输入有多组数据,每组只有一行,包含两个正整数a,b.最后一组a=0,b=0表示输入结束,不需要处理. Output 对于每组输入数据,输出ab各位数字的和的各位数字的和的各位数字的和的各位数字的和. Sample Input 2 3 5 7 0 0 Sample Output 8 5 思路: 数论定理:任何数除以9的余数等于各位数的和除