POJ 2992 Divisors (求因子个数)
题意:给n和k,求组合C(n,k)的因子个数。
这道题,若一开始先预处理出C[i][j]的大小,再按普通方法枚举2~sqrt(C[i][j])来求解对应的因子个数,会TLE。
所以得用别的方法。
在说方法前,先说一个n!的性质:
n!的素因子分解中的素数p的个数为
n/p+n/(p^2)+...+n/(p^k)+...
《ACM-ICPC程序设计系列 数论及应用》上的方法,200+ms:
首先先求解435以内的素因子。
然后预处理出j!中每个素因子的个数,公式如下:
num[j][i]=j/prime[i]+num[j/prime[i]][i];
设n!中素因子p的个数为:a=n/p+n/(p^2)+...+n/(p^k)+...
那么(n/p)!中素因子p的个数为:b=n/(p^2)+...+n/(p^k)+...
很显然a=b+n/p,因此可以利用上述递推公式预处理出所有的j!中每个素因子的个数。
接下来就可以预处理出C(i,j)的因子个数,然后一切就好办了。
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h> using namespace std;
const int maxn=;
bool isprime[maxn];
int prime[maxn];
int cnt=;
int num[maxn][maxn]; //num[i][j]表示i!中素因子prime[j]的个数。
long long C[maxn][maxn]; //C[i][j](0<=j<=i)表示组合C(i,j)的因子个数。
void init(){
memset(isprime,true,sizeof(isprime));
for(int i=;i<maxn;i++){
if(isprime[i]){
prime[cnt++]=i;
for(int j=i*;j<maxn;j+=i)
isprime[j]=false;
}
}
memset(num,,sizeof(num));
for(int i=;i<cnt;i++){
for(int j=;j<maxn;j++)
num[j][i]=j/prime[i]+num[j/prime[i]][i];
}
//预处理出C(i,j)的因子个数
for(int i=;i<maxn;i++){
for(int j=;j<i;j++){
C[i][j]=;
for(int k=;k<cnt;k++){
int d=num[i][k]-num[i-j][k]-num[j][k];
if(d)
C[i][j]*=d+;
}
}
}
}
int main()
{
init();
int n,k;
while(scanf("%d%d",&n,&k)!=EOF){
if(n==k ||k==)
printf("1\n");
else
printf("%I64d\n",C[n][k]);
}
return ;
}
我的方法没有预处理,每次读取n和k后,利用公式计算n!,k!,(n-k)!的各个因素的个数,最后再总的求。时间600多ms。
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h> using namespace std;
const int maxn=;
bool isprime[maxn];
int prime[maxn];
int cnt=;
int num[maxn];
void init(){
memset(isprime,true,sizeof(isprime));
for(int i=;i<maxn;i++){
if(isprime[i]){
prime[cnt++]=i;
for(int j=i*;j<maxn;j+=i)
isprime[j]=false;
}
}
}
//求n!的各个素因子的个数
void countnum1(int n){
for(int i=;i<cnt && prime[i]<=n;i++){
int c=,p=prime[i];
while(n/p){
c+=n/p;
p*=prime[i];
}
num[prime[i]]+=c; //在分子上,是+=c。 }
}
void countnum2(int n){
for(int i=;i<cnt && prime[i]<=n;i++){
int c=,p=prime[i];
while(n/p){
c+=n/p;
p*=prime[i];
}
num[prime[i]]-=c; //分母,是-=c
}
}
int main()
{
init();
int n,k;
while(scanf("%d%d",&n,&k)!=EOF){
memset(num,,sizeof(num));
countnum1(n);
countnum2(n-k);
countnum2(k);
long long ret=;
for(int i=;i<cnt;i++){
if(num[prime[i]]){
ret*=(num[prime[i]]+);
}
}
printf("%I64d\n",ret);
}
return ;
}
POJ 2992 Divisors (求因子个数)的更多相关文章
- Trailing Zeroes (I) LightOJ - 1028(求因子个数)
题意: 给出一个N 求N有多少个别的进制的数有后导零 解析: 对于一个别的进制的数要转化为10进制 (我们暂且只分析二进制就好啦) An * 2^(n-1) + An-1 * 2^(n-2) + `` ...
- Almost All Divisors(求因子个数及思维)
---恢复内容开始--- We guessed some integer number xx. You are given a list of almost all its divisors. Alm ...
- LightOj1028 - Trailing Zeroes (I)---求因子个数
题目链接:http://lightoj.com/volume_showproblem.php?problem=1028 题意:给你一个数 n (1<=n<=10^12), 然后我们可以把它 ...
- Easy Number Challenge(暴力,求因子个数)
Easy Number Challenge Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I ...
- poj 2992 Divisors (素数打表+阶乘因子求解)
Divisors Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9617 Accepted: 2821 Descript ...
- poj 2992 Divisors 整数分解
设m=C(n,k)=n!/((n-k)!*k!) 问题:求m的因数的个数 将m分解质因数得到 p1有a1个 p2有a2个 .... 因为每一个质因数能够取0~ai个(所有取0就是1,所有取ai就是m) ...
- POJ 2992 Divisors
每个数都可以分解成素数的乘积: 写成指数形式:n=p1^e1*p2^e2*...*pn^en:(p都是素数) 那么n的因数的数量m=(e1+1)*(e2+1)*...*(en+1): 所以用筛选法筛出 ...
- HDU-1492-The number of divisors(约数) about Humble Numbers -求因子总数+唯一分解定理的变形
A number whose only prime factors are 2,3,5 or 7 is called a humble number. The sequence 1, 2, 3, 4, ...
- Divisors (求解组合数因子个数)【唯一分解定理】
Divisors 题目链接(点击) Your task in this problem is to determine the number of divisors of Cnk. Just for ...
随机推荐
- [笔记]--在Windows下配置Git
安装就不多说了: 1.ls不能显示中文目录 解决办法:在git/etc/git-completion.bash中增加一行: alias ls='ls --show-control-chars --co ...
- 关于datagridview的一些操作
1.绑定datatable时,会显示出不需要显示的列可以加datagridview.AutoGenerateColumns = false; 2.如果datagridview的某列是数值型的,有小数, ...
- java的基本数据类型特征
java的数据类型分为基本数据类型和引用数据类型. 基本数据类型分为数值型.字符型(char).布尔型(boolean) 数值型变量 1.整数型 类型 占用存储空间 表示范围 byte 1字节Byte ...
- 如何在Eclipse中配置Tomcat
1.Eclipse EE 配置Tomcat Eclipse EE 主要用于Java Web开发和J2EE项目开发.Eclipse EE中配置Tomcat比较简单,新建一个Tomcat Server即可 ...
- c++性能测试
程序分析是以某种语言书写的程序为对象,对其内部的运作流程进行分析.程序分析的目的主要有三点:一是通过程序内部各个模块之间的调用关系,整体上把握程序的运行流程,从而更好地理解程序,从中汲取有价值的内容. ...
- windows phone 8.1 HttpWebRequest 请求服务器
public string SendGetRequest(string baseurl, string parameters) { string parassb = parameters; ) { b ...
- Go语言参数中的三个点是干什么的
Go语言函数中有三个点...表示为可变参数,可以接受任意个数的参数. 示例代码: package main import "fmt" func Greeting(prefix st ...
- iOS开发多线程篇—单例模式(ARC)
iOS开发多线程篇—单例模式(ARC) 一.简单说明: 设计模式:多年软件开发,总结出来的一套经验.方法和工具 java中有23种设计模式,在ios中最常用的是单例模式和代理模式. 二.单例模式说明 ...
- 【上传AppStore】iOS项目上传到AppStore步骤流程(第一章) - 上传新的app
1.登录developer.apple.com 2.点击member center后 然后如下图 3.点击certificates Identifiers 进下图 界面基本介绍请看图 : 4. 其次创 ...
- 团队开发---NABC分析
我们的软件初步构想的是版主同学们解决宿舍订桶装水的问题,随着夏季的来临,桶装水的需求量日益加大,而我们订水的过程中常常会遇到这样或那样的问题.再次我只对我们项目中可以直观的看到今日卖家总库存水量和剩余 ...