poj2992(Divisors)(阶乘因数分解)
2016-07-17 09:52
246 查看
暑假集训很忙,大概一周没写题解了,我会找时间把经典的题写题解(*)。
刚开始我的思路是先算(n-k+1)~n这个区间每个数的因数分解然后相加,减去1~k这个区间每个数的因数分解,当时完全没有想到超时(打表打完不超时,但调用输入输出立刻超时,卡得真是可以)。直接因数分解打表Tle,t了我一个晚上(^^)。于是,这就需要数学知识来优化。
首先,我们可以把所有的N以内的质数给打表求出来。
下面代码求的是1~num中分解后a的指数和
刚开始我的思路是先算(n-k+1)~n这个区间每个数的因数分解然后相加,减去1~k这个区间每个数的因数分解,当时完全没有想到超时(打表打完不超时,但调用输入输出立刻超时,卡得真是可以)。直接因数分解打表Tle,t了我一个晚上(^^)。于是,这就需要数学知识来优化。
首先,我们可以把所有的N以内的质数给打表求出来。
下面代码求的是1~num中分解后a的指数和
inline int cal(int a,int num) { if(a>num) return 0; return num/a+cal(a,num/a); }
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#include <string.h>
#include <queue>
#include <iterator>
#define MAXN 433
#define ms(X) memset(X,0,sizeof(X))
#define msc(X) memset(X,-1,sizeof(X))
typedef long long LL;
using namespace std;
int prime[91];
bool Is_prime[MAXN+1];
void getPrime(void)
{
ms(Is_prime);
ms(prime);
for(int i=2;i<=MAXN;i++)
{
if(!Is_prime[i]) prime[++prime[0]]=i;
for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++)
{
Is_prime[prime[j]*i]=true;
if(i%prime[j]==0) break;
}
}
}
inline int cal(int a,int num) { if(a>num) return 0; return num/a+cal(a,num/a); }
int main(int argc, char const *argv[])
{
getPrime();
int n,k;
while(scanf("%d %d",&n,&k)!=EOF)
{
if(k==0||n==k) {printf("1\n");continue;}
LL res=1;
for(int i=1;i<prime[0]&&prime[i]<=n;i++)
res*=(cal(prime[i],n)-cal(prime[i],k)-cal(prime[i],n-k)+1);
printf("%I64d\n",res );
}
return 0;
}
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- [数论]poj2635__The Embarrassed Cryptographer
- [二分图匹配]poj2446__Chessboard
- POJ1050 最大子矩阵和
- 用单调栈解决最大连续矩形面积问题