• BZOJ3000. Big Number


    题目

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

    对于100%的数据,有2≤N≤2^31, 2≤K≤200,数据组数T≤200。

    分析

    发现其实就是让我们求 (log_k{n!}) 的位数。

    暴力求就是 (ans=log_k{1}+log_k{2}+log_k{3}+...+log_k{n})

    然后这里有一个斯特林公式可以快速估算这个结果,数字越大越准确。

    这个可以变成:

    然后直接取 (log) 即可。

    数字小的时候我们暴力,大了就斯特林公式。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define inc(x,y,mod) (((x)+(y))>=(mod)?(x)+(y)-(mod):(x)+(y))
    #define dec(x,y,mod) ((x)-(y)<0?(x)-(y)+(mod):(x)-(y))
    #define rep(i,x,y) for(int i=(x);i<=(y);i++)
    #define per(i,y,x) for(int i=(y);i>=(x);i--)
    #define pc putchar
    #define PII pair<int,int>
    #define fi first
    #define se second
    #define db double
    #define mem(x,k) memset(x,k,sizeof(x))
    #define mec(x,y) memcpy(x,y,sizeof(x))
    #define close ios::sync_with_stdio(false)
    template<typename T>inline void cmax(T& a,const T b){a<b?a=b:0;}
    template<typename T>inline void cmin(T& a,const T b){a>b?a=b:0;}
    const int N=1e5+5,M=2e5+5,MOD=998244353,INF=1e9+7;
    ll n,k;
    const db Pi=acos(-1),e=exp(1.0);
    signed main(){
    	close;
    	while(~scanf("%lld%lld",&n,&k)){
    		if(n<=100000){
    			db ans=0;
    			rep(i,2,n) ans+=log(i)/log(k);
    			cout<<(ll)(1+ans)<<endl;
    		}
    		else{
    			db ans=0.5*log(2*Pi*n)/log(k)+n*log(n/e)/log(k);
    			cout<<(ll)(floor(ans))+1<<endl;
    		}
    	}
    	
    	return 0;
    }
    

    总结

    这个公式用于估算阶乘值的大小,更常用于估算其位数。

  • 相关阅读:
    软件工程课程总结
    c++第五次作业
    软件工程第四次作业
    c++第四次作业
    软件工程第三次作业
    c++第三次作业
    软件工程基础第二次作业
    c++第二次作业
    c++第一次作业
    软件工程基础第一次作业
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14905956.html
Copyright © 2020-2023  润新知