码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-08-12 15:40:41      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:clu   pen   long   规律   size   mil   can   http   for   

题目大意:给出一个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\n", ca++, H(n));
29     }
30     return 0;
31 }
View Code

 

  

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

标签:clu   pen   long   规律   size   mil   can   http   for   

原文地址:https://www.cnblogs.com/DynastySun/p/9462847.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!