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;
}

 

  

posted @ 2013-04-24 15:15  yefeng1627  阅读(279)  评论(0编辑  收藏  举报

Launch CodeCogs Equation Editor