• G


    /**
    题目:G - Harmonic Number (II)
    链接:https://vjudge.net/contest/154246#problem/G
    题意:给定一个数n,求n除以1~n这n个数的和。n达到2^31 - 1;
    思路:
    首先我们观察一下数据范围,2^31次方有点大,暴力会超时,所以我们看看有没有啥规律,假设 tmp 是 n/i 的值,当n == 10的时候(取具体值)
    当 tmp = 1 时,个数 是10/1 - 10/2 == 5个
    
    当 tmp = 2 时,个数 是10/2 - 10/3 == 2个
    
    当 tmp = 3 时,个数 是10/3 - 10/4 == 1个
    …………
    当 tmp = 10时,个数是10/10 - 10/11 == 1个
    所以我们发现有个规律了,当tmp == i 的时候,我们要求的个数就是 10/i - 10/(i+1),然后我们前1 — sqrt(n)个数的数值还是比较大的,但是数据范围变小了
    暴力可以求出来,剩下的 sqrt(n)+1 — n个数中 数据范围还是比较大,但是 n/i 的数据范围介于 1 - sqrt(n)之间,所以用我们找出的规律可以求出来,我们只需要
    两个for循环就搞定了,时间复杂度 O(sqrt(n)),完全可以,剩下的就是编写程序了
    
    自己手写就明白了。
    
    自己没做出来了,我原先想法:
    我简单测试了一下,不同的n/i没有多少。很多结果相同,是连续的。
    于是二分,每一次处理一段相同N/i的区间。一段一段区间处理。然而超时了。
    
    ac做法参考来源:https://yq.aliyun.com/articles/15323
    
    */
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int main()
    {
        //init();
        int T, cas=1, n;
        cin>>T;
        while(T--)
        {
            scanf("%d",&n);
            ll res = 0;
            int m = sqrt(n);
            for(int i = 1; i <= m; i++){
                res += n/i;
            }
            for(int i = 1; i <= m; i++){
                res += (n/i-n/(i+1))*i;
            }
            if(n/m==m){
                res -= m;
            }
            printf("Case %d: %lld
    ",cas++,res);
        }
        return 0;
    }
  • 相关阅读:
    Eclipse(MyEclipse)使用技巧——改动凝视字体大小
    C++标准库之 Lower_Bound, upper_Bound
    Mongodb地理空间索引
    AfxMessageBox和MessageBox差别
    具体解释VB中连接access数据库的几种方法
    C++中this指针的使用方法.
    秒杀多线程第四篇 一个经典的多线程同步问题
    设计模式学习03—抽象工厂模式
    Neutron中的Service类
    Opencv学习笔记(六)SURF学习笔记
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/6628891.html
Copyright © 2020-2023  润新知