【bzoj3000】Big Number 数论

题目描述

给你两个整数N和K,要求你输出N!的K进制的位数。

输入

有多组输入数据,每组输入数据各一行,每行两个数——N,K

输出

每行一个数为输出结果。

样例输入

2 5
2 10
10 10
100 200

样例输出

1
1
7
69


题解

数论

题目转化一下变为求$\lfloor\log_kn!\rfloor+1$,使用换底公式,问题转化为求$\log n$。

$n$有$2^31$之大,显然不能暴力去求。

这里需要用到Stirling公式:$n!\approx\sqrt{2\pi n}(\frac ne)^n$。这个公式在$n$较大时比较精确,因此可以直接套用;当$n$较小时精确度没有那么高,因此需要小范围暴力。

直接使用cmath中的函数对右半部分取对数即可(右半部分化简结果为$\frac 12\log 2\pi n$+n\log\frac ne),再除以$\log k$,下取整+1即为答案。

注意需要long long。

#include <cmath>
#include <cstdio>
const double pi = acos(-1) , e = exp(1);
int main()
{
    int n , k , i;
    while(~scanf("%d%d" , &n , &k))
    {
        if(n <= 100)
        {
            double ans = 0;
            for(i = 1 ; i <= n ; i ++ ) ans += log(i);
            printf("%d\n" , (int)floor(ans / log(k)) + 1);
        }
        else printf("%lld\n" , (long long)floor((log(2 * pi * n) / 2 + log(n / e) * n) / log(k)) + 1);
    }
    return 0;
}

 

 

转载于:https://www.cnblogs.com/GXZlegend/p/7707943.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值