【HDU4473】Exam(数学题)

本文探讨了一道数学题目,旨在求解一个特定的数学序列问题。通过巧妙的转换,将原问题转化为求解满足特定条件的解的数量。文章详细介绍了分类讨论的解题思路,包括当三个数相等、两个数相等以及三个数互不相等时的解法,并提供了C++代码实现。

点此看题面

大致题意:\(f(x)=\sum[(a*b)|x]\),求\(\sum_{x=1}^nf(x)\)

转化题意

将题意进行转换,我们就可以发现,我们要求的\(ans\)就是满足\(x*y*z\le n\)的解的个数(这应该还是比较显然的)。

大致思路

此题无非就是一个分类讨论

假设\(a\le b\le c\)

  • 当三个数全部相等时,求出的解只有一种排列方式。
  • 当三个数中有两个数相等时,求出的解有三种排列方式。
  • 当三个数互不相等时,求出的解共有六种排列方式。

按照这种思路,就能很快速地求出答案了。

注意排除重复的情况。

代码

#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL n;
class Class_MathSolver
{
    public:
        inline void Solve(LL x)
        {
            register LL i,j,k,ans=0;
            for(i=1;i*i*i<=x;++i) ++ans;//对于三数相等的情况,虽然这样慢,但能避免精度误差
            for(i=1;i*i<=x;++i) if((j=x/(i*i))>=i) ans+=3*(j-1);else ans+=3*j;//对于两数相等的情况,注意不能把三数相等的情况包括在内
            for(i=1;i*i*i<=x;++i) for(j=i+1;j<=x;++j) if((k=x/(i*j))>=j) ans+=6*(k-j);else break;//对于三数互不相等的情况,同样注意排除重复的情况
            printf("%lld\n",ans);
        }
}MathSolver;
int main()
{
    register int T=0;
    while(~scanf("%lld",&n)) printf("Case %d: ",++T),MathSolver.Solve(n);
    return 0;
}

转载于:https://www.cnblogs.com/chenxiaoran666/p/HDU4473.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值