NEUOJ1403(数学~)

题目内容是求[n/1]+[n/2]+[n/3]+..+[n/3]。

累计当前已经处理过的分母,假设为pre,而且当前这个结果为i,那么i这个结果出现的次数是i*(n-pre-[n/(i+1)])。这样枚举到sqrt(n)以后结果出现的次数变得很少并且相隔很大,所以到此换一种枚举方法也就是从1开始枚举下标,一直到sqrt(n),边界处理稍微恶心一点。

#include <bits/stdc++.h>
using namespace std;

long long n;

long long solve () {
    long long pre = 0, ans = 0;
    long long Max = sqrt (n), cur, out;
    for (long long i = 1; i <= Max; i++) {
        cur = n-pre-(long long)(n/(i+1));
        pre += cur;
        ans += cur*i;
        if (i == Max) {
            out = i;
            break;
        }
    }
    for (long long i = 1; ; i++) {
        if ((long long)(n/i) == out)
            break;
        ans += (long long) (n/i);
    }
    return ans;
}

int main () {
    int t, kase = 0;
    scanf ("%d", &t);
    while (t--) {
        scanf ("%lld", &n);
        printf ("Case%d: %lld\n", ++kase, solve ());
    }
    return 0;
}
这本身是很水的题目。

不过有个很有趣的结论,发现f(n) = f(n-1) + g(n),f(n)是本题的结果,g(n)刚好是n的所有因数的个数。因此这道题也就是求1~n所有数的因数的个数和。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值