Description
给你两个整数N和K,要求你输出N!的K进制的位数。
对于100%的数据,有2≤N≤2^31, 2≤K≤200,数据组数T≤200。
Solution
显然答案就是logk(n!)\log_k\left(n!\right)logk(n!) ,然后就不会做了OTZ
斯特林公式:n!≈2πn(ne)nn!\approx\sqrt{2\pi n}{\left(\frac{n}{e}\right)}^nn!≈2πn(en)n
于是有ans≈logk[2πn(ne)n]ans\approx \log_k\left[{\sqrt{2\pi n}{\left(\frac{n}{e}\right)}^n}\right]ans≈logk[2πn(en)n]
≈12logk(2πn)+n(logkn−logke)\approx \frac{1}{2}\log_k\left(2\pi n\right)+n\left(\log_kn-\log_ke\right)≈21logk(2πn)+n(logkn−logke)
log可以换底,其中pi=acos(-1),e=exp(1)
Code
#include <stdio.h>
#include <string.h>
#include <math.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long LL;
const double pi=acos(-1);
const double e=exp(1);
const double eps=1e-7;
int main(void) {
for (LL n,k;~scanf("%lld%lld",&n,&k);) {
double tmp=0;
if (n<=1000000) {
rep(i,1,n) {
tmp+=log(i)/log(k);
}
printf("%lld\n", 1+(LL)tmp);
continue;
}
LL res=0;
res=eps+0.5*log(2.0*pi*n)/log(k)+n*(log(n)-log(e))/log(k);
printf("%lld\n", res+1);
}
return 0;
}