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 ...
随机推荐
- Oracle 错误代码
ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 ORA-00020: 超出 ...
- Android--将字节数转化为B,KB,MB,GB的方法
//将字节数转化为MB private String byteToMB(long size){ long kb = 1024; long mb = kb*1024; long gb = mb*1024 ...
- Android 文档之viewAnimator
一.结构 public class ViewAnimator extends FrameLayout java.lang.Object android.view.View android.view.V ...
- 网络爬虫by pluskid
网络爬虫(Web Crawler, Spider)就是一个在网络上乱爬的机器人.当然它通常并不是一个实体的机器人,因为网络本身也是虚拟的东西,所以这个“机器人”其实也就是一段程序,并且它也不是乱爬,而 ...
- 解决sharepoint 2010 用户配置文件同步服务 正在启动
用户配置文件同步服务一直显示“正在启动”,而且无法停止,如下办法可以停止这个服务: 在sharepoint power shell 中执行下面的命令: Get-spserviceinstance 获取 ...
- JAVA类与对象(七)------继承
理解:继承可以理解为一个对象获取属性的过程.如果类A是类B的父类,而类B是类C的父类,我们也称C是A的子类,类C是从类A继承而来. 在java中,类的继承是单一继承,也就是说,一个子类只能拥有一 ...
- JavaScript插入节点
1. document.write("<p>This is inserted.</p>"); 该方法必须加在HTML文档内,违背了结构行为分离原则,不推荐. ...
- 微软职位内部推荐-Senior Software Engineer -Web
微软近期Open的职位: Location: Beijing, China The Office App Services team is working on the powerful Office ...
- “我爱淘”冲刺阶段Scrum站立会议7
完成任务: 大事不好,今天的任务还没有完成,没有通过xml文件通过服务器显示到软件中. 计划任务: 实现通过服务器将xml文件中的数据显示到软件中. 遇到问题: 服务器已经配好,并且解析xml文件的代 ...
- 搭建SpringMVC+MyBatis开发框架四
在src/main下面新建一个resouces文件夹,我们继续配置一些资源 1.新增applicationContext.xml:  <?xml version="1.0" ...