LightOJ - 1245 Harmonic Number (II) (找规律)

Posted dynastysun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LightOJ - 1245 Harmonic Number (II) (找规律)相关的知识,希望对你有一定的参考价值。

题目大意:给出一个n(1 <= n < 2^31)求出H(n)的结果,H(n)的定义为下:

技术分享图片

分析:对于一个n,设 t = n / i:

  满足 t >= 1的有多少个呢?  有 n / 1 个。

  满足 t >= 2的有多少个呢?  有 n / 2 个。

  ……

  满足 t >= k的有多少个呢?  有 n / k 个。

以上结论不难发现,我们再进一步就能发现:

  满足 t == 1 的有 n/1 - n/2 个

  满足 t == 2 的有 n/2 - n/3 个

  ……

  满足 t == k 的有 n/k - n/(k+1) 个

发现这个规律,我们就需要考虑这个 t 枚举到哪呢?t 从1 枚举 到 n 肯定是对的,但是时间上不允许,我们可以改进一下,我们在枚举 t >= i 的时候,我们可以顺便计算出满足 t >= n/i 的有多少个(举个例子,n == 10,t >= 2的有5个,那么t>=5的就有2个)。这样一来时间复杂度就变为O(√n)了,这样就足够了。详情见代码:

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <cmath>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 typedef unsigned long long ULL;
 9 
10 LL H(int n){
11     LL ans = 0;
12     int m = sqrt(n+0.5);
13     for(int i = 2; i <= m; ++i){
14         ans += (LL)(i-1)*(n/(i-1)-n/i);
15         ans += n/(i-1);
16     }
17     ans += m*(n/m - m);
18     ans += n/m;
19     return ans;
20 }
21 
22 int main(){
23     int T, ca = 1;
24     scanf("%d", &T);
25     while(T--){
26         int n;
27         scanf("%d", &n);
28         printf("Case %d: %lld
", ca++, H(n));
29     }
30     return 0;
31 }
View Code

 

  

以上是关于LightOJ - 1245 Harmonic Number (II) (找规律)的主要内容,如果未能解决你的问题,请参考以下文章

LightOJ - 1245 Harmonic Number (II) (找规律)

LightOJ - 1245 Harmonic Number (II) 求同值区间的和

LightOJ 1234Harmonic Number

LightOJ1234 Harmonic Number 调和级数求和

LightOJ 1245 数学题,找规律

I - Harmonic Number LightOJ - 1234 (分段打表+暴力)