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

暑假集训很忙,大概一周没写题解了,我会找时间把经典的题写题解(*)。

刚开始我的思路是先算(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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值