您的位置:首页 > 其它

poj2992(Divisors)(阶乘因数分解)

2016-07-17 09:52 246 查看
暑假集训很忙,大概一周没写题解了,我会找时间把经典的题写题解(*)。

刚开始我的思路是先算(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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj