[BZOJ3000] Big Number (Stirling公式)
Description
给你两个整数N和K,要求你输出N!的K进制的位数。
Input
有多组输入数据,每组输入数据各一行,每行两个数——N,K
Output
每行一个数为输出结果。
Sample Input
2 5
2 10
10 10
100 200
2 10
10 10
100 200
Sample Output
1
1
7
69
1
7
69
HINT
对于100%的数据,有2≤N≤2^31, 2≤K≤200,数据组数T≤200。
Source
Solution
安利一个高深的公式:Stirling公式
用这个公式,当n较大时很精确,而且n较小时误差也不大。
这道题的答案是 logk(n!)+1
= logk((2πn)0.5 * (n/e)n)
= 0.5logk(2πn) + n(logk(n) - logk(e))
1 #include <bits/stdc++.h> 2 using namespace std; 3 const double PI = acos(-1.0), E = exp(1.0); 4 double log(double a, double b) 5 { 6 return log(b) / log(a); 7 } 8 9 int main() 10 { 11 double n, k, ans; 12 while(cin >> n >> k) 13 { 14 ans = 1; 15 if(n <= 1000) 16 for(double i = 1; i <= n; i += 1) 17 ans += log(k, i); 18 else 19 { 20 ans += log(k, 2 * PI * n) / 2; 21 ans += n * (log(k, n) - log(k, E)); 22 } 23 cout << (long long)ans << endl; 24 } 25 return 0; 26 }