zoukankan      html  css  js  c++  java
  • hdu 4473 Exam 构造枚举

    题意:

      定义  f(x) = { num | a*b| x } , 求 \sum { f(x) } , x <= 10^11

    思路:

      题目等价于求 a*b*c <= n 的数量.

      假定 a <= b <= c. 则 a <= n^(1/3) , b <= n^(1/2) 

      所以我们可以通过枚举 a,b 计算出数量,时间复杂度未 O(n^(2/3))

      对于枚举的 a, b, c; 有三种情况

      1 . 三个相等  a, a, a 则只需要计算一次 ,  

         数量为:  n^(1/3)

      2.  二个相等,      a, a, b or a, b, b   则需要计算 C(1,3) = 3 次    

        数量为: n/(a*a) - a   and   (n/a)^(1/2) - a

      3.  三个都不相等 a, b, c , 则方案数为 P(3,3) = 6 次

          数量为:    n/(a*b) - b 

      另外要注意的是,  直接用pow(n,m) 求得的值会 四舍五入.要注意  保证 m*m <= n  or  m*m*m <= n 中最大的m

    View Code
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    
    typedef long long LL;
    
    LL pow2(LL x){
        LL m = pow(x,0.5);
        while(m*m<=x) m++;
        while(m*m>x) m--;
        return m;
    }
    LL pow3(LL x){
        LL m = pow(x,1./3);
        while(m*m*m<=x) m++;
        while(m*m*m>x ) m--;
        return m;
    }
    int main(){
        int Case = 1;    
        LL n;
        while( scanf("%lld", &n) != EOF){
            LL A = pow3(n), res = A;    
            for(LL a = 1; a <= A; a++){
                LL ni = n/a, k = pow2(ni);
                res += 1LL*( (ni/a-a) + (k-a) )*3;
                for(LL b = a+1; b <= k; b++){
                        res += 1LL*(ni/b-b)*6;
                }    
            }    
            printf("Case %d: %lld\n",Case++, res );
        }    
        return 0;
    }

      

  • 相关阅读:
    中位数相关
    带权并查集
    组合数相关、多重集组合数
    LIS最长上升子序列
    提高你css技能的css开发技巧
    如何让搜索引擎抓取AJAX内容?
    Javascript异步编程的4种方法
    前端自动化构建工具gulp
    前端自动化构建工具
    git使用
  • 原文地址:https://www.cnblogs.com/yefeng1627/p/3040263.html
Copyright © 2011-2022 走看看