Description
给你两个整数N和K,要求你输出N!的K进制的位数。
对于100%的数据,有2≤N≤2^31, 2≤K≤200,数据组数T≤200。
Solution
显然答案就是 log k ( n ! ) \log_k\left(n!\right) logk(n!) ,然后就不会做了OTZ
斯特林公式: n ! ≈ 2 π n ( n e ) n n!\approx\sqrt{2\pi n}{\left(\frac{n}{e}\right)}^n n!≈2πn(en)n
于是有
a
n
s
≈
log
k
[
2
π
n
(
n
e
)
n
]
ans\approx \log_k\left[{\sqrt{2\pi n}{\left(\frac{n}{e}\right)}^n}\right]
ans≈logk[2πn(en)n]
≈
1
2
log
k
(
2
π
n
)
+
n
(
log
k
n
−
log
k
e
)
\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;
}