除数函数(约数个数函数)前缀和

P r o b l e m \color{red} {Problem} Problem

Description
查 询 [ 1 − n ] 所 有 数 的 约 数 和 。 查询[1-n]所有数的约数和。 [1n]


Solution
朴 素 考 虑 [ 1 − n ] 的 约 数 个 数 的 和 。 也 就 是 考 虑 每 个 约 数 的 贡 献 ( 出 现 了 多 少 次 ) 朴素考虑 [1-n]的约数个数的和。也就是考虑每个约数的贡献(出现了多少次) [1n]()
枚 举 每 一 个 约 数 i 其 出 现 了 ⌊ n i ⌋ 次 枚举每一个约数 i 其出现了 \lfloor{\frac{n}{i}}\rfloor 次 iin
于 是 答 案 a n s = ∑ i = 1 n ⌊ n i ⌋ 于是答案 ans = \sum^{n}_{i=1} \lfloor{\frac{n}{i}}\rfloor ans=i=1nin
但 是 n 为 1 e 9 显 然 枚 举 是 会 超 时 的 但是 n 为 1e9 显然枚举是会超时的 n1e9
我 们 考 虑 一 个 定 理 ⌊ n i ⌋ 的 取 值 只 有 n 种 我们 考虑一个定理 \lfloor{\frac{n}{i}}\rfloor的取值只有 \sqrt n 种 inn
也 就 是 说 对 于 不 同 的 i , ⌊ n i ⌋ 的 取 值 大 部 分 是 一 样 的 。 那 么 我 们 跳 着 取 就 好 了 也就是说 对于不同的i,\lfloor{\frac{n}{i}}\rfloor的取值大部分是一样的。那么我们跳着取就好了 i,in
⌊ n i ⌋ 的 值 出 现 的 范 围 为 [ i , ⌊ n ⌊ n i ⌋ ⌋ ] \lfloor{\frac{n}{i}}\rfloor的值出现的范围为 [i,\lfloor\frac{n}{\lfloor{\frac{n}{i}}\rfloor}\rfloor] in[i,inn]
o k 问 题 就 解 决 了 ok 问题就解决了 ok
举 个 例 子 举个例子
n = 12 n = 12 n=12

因 数 i ⌊ n i ⌋ 出 现 的 区 间 ⌊ n i ⌋ 出 现 的 次 数 因数i\qquad\lfloor{\frac{n}{i}}\rfloor \qquad 出现的区间\qquad \lfloor{\frac{n}{i}}\rfloor 出现的次数 iinin

1 12 [ 1 , 1 ] 1 1\qquad\qquad12\qquad\qquad[1,1]\qquad\qquad1 112[1,1]1

2 6    [ 2 , 2 ] 1 2\qquad\qquad6\qquad\qquad\ \ [2,2]\qquad\qquad1 26  [2,2]1

3 4    [ 3 , 3 ] 1 3\qquad\qquad4\qquad\qquad\ \ [3,3]\qquad\qquad1 34  [3,3]1

4 3    [ 4 , 4 ] 1 4\qquad\qquad3\qquad\qquad\ \ [4,4]\qquad\qquad1 43  [4,4]1

5 2    [ 5 , 6 ] 2 ( 因 为 12 6 = 2 ) 5\qquad\qquad2\qquad\qquad\ \ [5,6]\qquad\qquad2\qquad\qquad(因为\frac{12}{6}=2) 52  [5,6]2(612=2)

7 1    [ 7 , 12 ]    6 7\qquad\qquad1\qquad\qquad\ \ [7,12]\qquad\quad\ \ 6 71  [7,12]  6


Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
int main()
{
    ll n;int caset;
    scanf("%d",&caset);
    while(caset--) {
        scanf("%lld",&n);
        ll res = 0;
        for(int i=1;i<=n;) {
            int r = n/(n/i)+1;
            res += (n/i) * (r - i);
            i = r;
        }
        printf("%lld\n",res);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值