Exam----HDU4473----数学题

本文详细解读HDU 4473 题目,通过转换条件并利用数学分析,提供高效计算方法及代码实现。重点在于理解将原题条件转化以及算法优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4473

本文转自:http://www.cnblogs.com/hundundm/archive/2012/11/17/2775191.html

题目意思:
  定义f(x) = 满足(a * b)|x的有序对(a,b)的个数。
  然后输入一个n,求f(1) + f(2) + ... + f(n)
废话不多说,此题的关键在于:
  把原题的条件(a * b)|x 转化为 a * b * y = x
  然后就很好计算了,就是,输入一个n,计算有多少有序对(a, b ,y)满足a*b*y<=n
  不妨设a<=b<=y
  则,a<=n^(1/3) , b<=sqrt(n/a)
  那么
    对于三个数字都相同的情况,只计算一次: i i i
    对于三个数字中有两个相同的情况,计算3次: i i j, i j i, j i i
    对于均不相同的情况,计算6次: a b y ,a y b ,b a y ,b y a, y a b ,y b a

代码贴自己的:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

#define LL long long

LL pow2(LL n)
{
    LL m = pow(n,0.5);
    while(m*m<n) m++;
    while(m*m>n) m--;
    return m;
}

LL pow3(LL n)
{
    LL m = pow(n,1.0/3);
    while(m*m*m<n)m++;
    while(m*m*m>n)m--;
    return m;
}


int main()
{
    LL n;
    int ca = 1;
    while(~scanf("%I64d",&n))
    {
        LL ans = 0;
        LL m = pow3(n);
        ans = m;
        for(int i=1;i<=m;i++)
        {
            LL ni = n/i;
            LL k = pow2(ni);
            ans += (ni/i-i+k-i)*3;
            for(int j=i+1;j<=k;j++)
            {
                ans += (ni/j-j)*6;
            }
        }
        printf("Case %d: %I64d\n",ca++,ans);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值