• LightOJ1245 Harmonic Number (II) —— 规律


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

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

    I was trying to solve problem '1234 - Harmonic Number', I wrote the following code

    long long H( int n ) {
        long long res = 0;
        for( int i = 1; i <= n; i++ )
            res = res + n / i;
        return res;
    }

    Yes, my error was that I was using the integer divisions only. However, you are given n, you have to find H(n) as in my code.

    Input

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

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

    Output

    For each case, print the case number and H(n) calculated by the code.

    Sample Input

    Output for Sample Input

    11

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    2147483647

    Case 1: 1

    Case 2: 3

    Case 3: 5

    Case 4: 8

    Case 5: 10

    Case 6: 14

    Case 7: 16

    Case 8: 20

    Case 9: 23

    Case 10: 27

    Case 11: 46475828386

    题意:

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

    题解:

    1.由于n<=2^31,直接暴力不不可能的。

    2.手写一下可发现一个规律, 当 n/i = k时, i的范围为 (n/(k+1), n/k],即有n/k- n/(k+1) 个 i 使得n/i = k。

    3.有了上述结论之后,就可以降低暴力程度了,设 m = sqrt(n)。先从1枚举到m,求出n/i的和,这样 [1,m] 这个区间的求值就解决了,还剩 [m+1, n] 这个区间:从m递减枚举到1,求出k*(n/k - n/(k+1))的和,这样就求出了[ n/m, n]的值,当 n/m==m时,即开始下标为m,则区间为[m,n],所以在m的位置重复计算了,需要减去m;当n/m!=m,即n/m>m时,其实下标为m+1,所以区间为 [m+1,n]。

    代码如下:

     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 int main()
    21 {
    22     int T, n, kase = 0;
    23     scanf("%d", &T);
    24     while(T--)
    25     {
    26         scanf("%d", &n);
    27         int m = sqrt(n);
    28 
    29         LL ans = 0;
    30         for(int i = 1; i<=m; i++) ans += n/i;
    31         for(int i = 1; i<=m; i++) ans += 1LL*i*(n/i - n/(i+1));
    32         if(n/m==m) ans -= m;
    33         printf("Case %d: %lld
    ", ++kase, ans);
    34     }
    35 }
    View Code
  • 相关阅读:
    (IDEA) VCS-->Import Into Version Control没有Share Project(Subversion)这个选项。
    Maven学习笔记(二)—— 整合SSH框架
    Maven学习笔记(一)—— Maven基础
    使用IDEA完成maven整合SSH框架时抛出Hibernate : Mapping (RESOURCE) not found
    mysql性能的检查和优化方法
    每个php程序员都应该知道的15个最佳PHP库
    linux oracle 11g 漏洞补丁升级
    linux 启动MongoDB
    linux 7 查看oracle 11g版本号
    linux 清除缓存命令
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8366296.html
Copyright © 2020-2023  润新知