BZOJ 3000(Big Number-Stirling公式求n!近似值)
3000: Big Number
Time Limit: 2 Sec Memory Limit: 128 MB
Submit: 220 Solved: 62
[Submit][Status]
Description
的K进制的位数。
Input
有多组输入数据。每组输入数据各一行,每行两个数——N。K
Output
每行一个数为输出结果。
Sample Input
2 10
10 10
100 200
Sample Output
1
7
69
对于100%的数据,有2≤N≤2^31, 2≤K≤200。数据组数T≤200。
HINT
Source
本题须要用到Stirling公式
∴位数=log10(n!)+1
方案1:[WA]n!
不断div k
- #include<cstdio>
- #include<cstring>
- #include<cstdlib>
- #include<algorithm>
- #include<functional>
- #include<iostream>
- #include<cmath>
- #include<cctype>
- #include<ctime>
- using namespace std;
- #define For(i,n) for(int i=1;i<=n;i++)
- #define Fork(i,k,n) for(int i=k;i<=n;i++)
- #define Rep(i,n) for(int i=0;i<n;i++)
- #define ForD(i,n) for(int i=n;i;i--)
- #define RepD(i,n) for(int i=n;i>=0;i--)
- #define Forp(x) for(int p=pre[x];p;p=next[p])
- #define Lson (x<<1)
- #define Rson ((x<<1)+1)
- #define MEM(a) memset(a,0,sizeof(a));
- #define MEMI(a) memset(a,127,sizeof(a));
- #define MEMi(a) memset(a,128,sizeof(a));
- #define INF (2139062143)
- #define F (100000007)
- long long mul(long long a,long long b){return (a*b)%F;}
- long long add(long long a,long long b){return (a+b)%F;}
- long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
- typedef long long ll;
- typedef long double ld;
- ld log(ll a,int b){}
- int main()
- {
- // freopen("bzoj3000.in","r",stdin);
- // freopen(".out","w",stdout);
- ll n;int k;
- while (scanf("%lld%d",&n,&k)!=EOF)
- {
- if (n<=10000)
- {
- ll ans=0,p=1;
- Fork(i,2,n)
- {
- p*=i;
- while (p>=k) {p/=k,ans++;}
- cout<<i<<':'<<p<<' '<<ans<<endl;
- }
- if (p) ans++;
- printf("%lld\n",ans);
- }
- }
- return 0;
- }
可是这样做是错的。TNT
理由是不断div k 会把原来小的部分删掉
方案2:logk(n!)=log(1)+log(2)+...+log(n)
效率为O(n),显然也不行
于是最好还是用Stirling公式求近似值
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbmlrZTBnb29k/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
位数=logk(n!)+1
≈ logk(sqrt(2πn)*(n/e)^n+1
= logk(sqrt(2πn))+log[(n/e)^n]+1
=1/2*logk(2πn)+nlog(n/e)+1
=0.5*logk(2πn)+nlog(n/e)+1
=0.5*logk(2πn)+nlog(n)-nlog(e)+1
PS:pi=acos(-1.0),e=exp(1)
PS2:eps的存在是为了防止n=2,k=2这样刚好的情况出现,这个时候向上取整要多取1位
- #include<cstdio>
- #include<cstring>
- #include<cstdlib>
- #include<algorithm>
- #include<functional>
- #include<iostream>
- #include<cmath>
- #include<cctype>
- #include<ctime>
- using namespace std;
- #define For(i,n) for(int i=1;i<=n;i++)
- #define Fork(i,k,n) for(int i=k;i<=n;i++)
- #define Rep(i,n) for(int i=0;i<n;i++)
- #define ForD(i,n) for(int i=n;i;i--)
- #define RepD(i,n) for(int i=n;i>=0;i--)
- #define Forp(x) for(int p=pre[x];p;p=next[p])
- #define Lson (x<<1)
- #define Rson ((x<<1)+1)
- #define MEM(a) memset(a,0,sizeof(a));
- #define MEMI(a) memset(a,127,sizeof(a));
- #define MEMi(a) memset(a,128,sizeof(a));
- #define INF (2139062143)
- #define F (100000007)
- long long mul(long long a,long long b){return (a*b)%F;}
- long long add(long long a,long long b){return (a+b)%F;}
- long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
- typedef long long ll;
- typedef long double ld;
- ld const pi=acos(-1.0),e=exp(1),eps=1e-10;
- ld log(ld a,ld b){return log(a)/log(b);}
- int main()
- {
- // freopen("bzoj3000.in","r",stdin);
- // freopen(".out","w",stdout);
- ll n;int k;
- cout.setf(ios::fixed);
- cout.precision(0);
- while (scanf("%lld%d",&n,&k)!=EOF)
- {
- if (n<=10000)
- {
- ld ans=0.0;
- For(i,n) ans+=log(i);
- ans/=log(k);
- ans=ceil(ans+eps);
- cout<<ans<<endl;
- }
- else
- {
- cout<<ll(0.5*log(2*pi*n,k)+n*log(n,k)-n*log(e,k))+1<<endl;
- }
- }
- return 0;
- }
BZOJ 3000(Big Number-Stirling公式求n!近似值)的更多相关文章
- BZOJ 3000: Big Number (数学)
题目: https://www.lydsy.com/JudgeOnline/problem.php?id=3000 题解: 首先n很大,O(n)跑不过,那么就要用一些高端 而且没听过 的东西——sti ...
- [BZOJ3000] Big Number (Stirling公式)
Description 给你两个整数N和K,要求你输出N!的K进制的位数. Input 有多组输入数据,每组输入数据各一行,每行两个数——N,K Output 每行一个数为输出结果. Sample I ...
- 斯特林(Stirling)公式 求大数阶乘的位数
我们知道整数n的位数的计算方法为:log10(n)+1n!=10^m故n!的位数为 m = log10(n!)+1 lgN!=lg1+lg2+lg3+lg4+lg5+................. ...
- POJ1423 - Big Number(Stirling公式)
题目大意 求N!有多少位 题解 用公式直接秒杀... 代码: #include<iostream> #include<cmath> using namespace std; # ...
- bzoj 3000 Big Number 估算n!在k进制下的位数 斯特林公式
题目大意 求n!在k进制下的位数 2≤N≤2^31, 2≤K≤200 分析 作为数学没学好的傻嗨,我们先回顾一下log函数 \(\log_a(b)=\frac 1 {log_b(a)}\) \(\lo ...
- [POJ1423]Stirling公式的应用
Stirling公式: n!约等于sqrt(2*pi*n)*(n/e)^n 另外,e约等于2.71828182845409523... 试了一下发现math库里面并不能像pi一样直接调e但是发现挺好记 ...
- java实现第四届蓝桥杯公式求值
公式求值 输入n, m, k,输出图1所示的公式的值.其中C_n^m是组合数,表示在n个人的集合中选出m个人组成一个集合的方案数.组合数的计算公式如图2所示. 输入的第一行包含一个整数n:第二行包含一 ...
- Excel公式-求最低价网站名字
p{ font-size: 15px; } .alexrootdiv>div{ background: #eeeeee; border: 1px solid #aaa; width: 99%; ...
- 斯特林公式 ——Stirling公式(取N阶乘近似值)(转)
斯特灵公式是一条用来取n阶乘近似值的数学公式.一般来说,当n很大的时候,n阶乘的计算量十分大,所以斯特灵公式十分好用.从图中可以看出,即使在n很小的时候,斯特灵公式的取值已经十分准确. 公式为: ...
随机推荐
- 客户端Git的常用命令
(1)git clone 服务器用户名@服务器IP:~/Git目录/.git 功能:下载服务器端Git仓库中的文件或目录到本地当前目录. (2)git status 功能:查看Git仓库中的文件状态. ...
- webService 三要素
WebService(jax-ws)三要素 SOAP: 基于HTTP协议,采用XML格式,用来传递信息的格式. WSDL: 用来描述如何访问具体的服务.(相当于说明书) UDDI: 用户自己可以按UD ...
- Openshift 节点添加和删除
1.节点添加 在新节点上编辑yum源/etc/yum.repo.d/ocp.repo /etc/hosts在主和节点上都加上相应信息 编辑host文件,加入 [OSEv3:children] mast ...
- Spring Dataflow批处理框架在OCP上的部署
详细参考 https://donovanmuller.blog/spring-cloud-dataflow-server-openshift/docs/1.2.1.RELEASE/reference/ ...
- latex 三个不同的图放在一行且每个图都有注释
\begin{figure}[htbp] \begin{minipage}[t]{0.3\linewidth} \centering \includegraphics[width=.2.0.eps} ...
- OCP试题解析之053-17 CONFIGURE CONTROLFILE AUTOBACKUP ON
17.You configure AUTOBACKUP to ON in an RMAN session. When will RMAN back up the control file? (Choo ...
- Linux中文乱码问题终极解决方法
方法一: 修改/root/.bash_profile文件,增加export LANG=zh_CN.GB18030该文件在用户目录下,对于其他用户,也必须相应修改该文件. 使用该方法时putty能显示中 ...
- TensorFlow进阶(三)---变量的创建、初始化
变量的的创建.初始化.保存和加载 其实变量的作用在语言中相当,都有存储一些临时值的作用或者长久存储.在Tensorflow中当训练模型时,用变量来存储和更新参数.变量包含张量(Tensor)存放于内存 ...
- Oracle两个时间段是否重合、冲突
经常会碰到比较两个时间段是否冲突的情况. 思路1 最开始比较2个时间是否的思路是,时间段的重叠. 但是比较时间段重叠的情况,就有几种情况, 1. 时间前段冲突. 时间A: 2015-10-01 ...
- 手写Json转换
在做项目的时候总是要手动将集合转换成json每次都很麻烦,于是就尝试着写了一个公用的方法,用于转换List to json: using System; using System.Collection ...