LightOJ1234 Harmonic Number —— 分区打表

题目链接:https://vjudge.net/problem/LightOJ-1234

1234 - Harmonic Number
Time Limit: 3 second(s) Memory Limit: 32 MB

In mathematics, the nth harmonic number is the sum of the reciprocals of the first n natural numbers:

In this problem, you are given n, you have to find Hn.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n ≤ 108).

Output

For each case, print the case number and the nth harmonic number. Errors less than 10-8 will be ignored.

Sample Input

Output for Sample Input

12

1

2

3

4

5

6

7

8

9

90000000

99999999

100000000

Case 1: 1

Case 2: 1.5

Case 3: 1.8333333333

Case 4: 2.0833333333

Case 5: 2.2833333333

Case 6: 2.450

Case 7: 2.5928571429

Case 8: 2.7178571429

Case 9: 2.8289682540

Case 10: 18.8925358988

Case 11: 18.9978964039

Case 12: 18.9978964139

题意:

对于一个数n,输出 sigma(1/k),1<=k<=n。

题解:

1.一开始想离线做,结果发现输入完一个测试数据就必须输出,不能离线。

2. 由于n<=1e8,开一个1e8大小的数组是不可能的,那么可以尝试开一个1e6的数组,然后每隔100就存一个数据,分区打表。

3.假设能开1e8大小的数组,那么经过预处理后,那么查询只需O(1),这种处理方式是完全偏向于时间;如果不开数组,每次都重新计算,那么每次查询需O(n),而n可高达1e7,这种处理方式完全偏向于空间。可见两种极端的处理方式都无法解决问题,而需在这两者之间作个权衡,人生也如此!

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <cmath>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <string>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 const int INF = 2e9;
15 const LL LNF = 9e18;
16 const int mod = 1e9+7;
17 const int MAXM = 1e5+10;
18 const int MAXN = 1e6+10;
19 
20 double table[MAXN];
21 void init()
22 {
23     double s = 0;
24     for(int i = 1; i<=100000005; i++)
25     {
26         s += 1.0/i;
27         if(i%100==0) table[i/100] = s;
28     }
29 }
30 
31 int main()
32 {
33     init();
34     int T, n, kase = 0;
35     scanf("%d", &T);
36     while(T--)
37     {
38         scanf("%d", &n);
39         double s = table[n/100];
40         for(int i = n/100*100+1; i<=n; i++)
41             s += 1.0/i;
42 
43         printf("Case %d: %.10f
", ++kase, s);
44     }
45 }
View Code
原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8366214.html