P r o b l e m \color{red} {Problem} Problem
Description
查
询
[
1
−
n
]
所
有
数
的
约
数
和
。
查询[1-n]所有数的约数和。
查询[1−n]所有数的约数和。
Solution
朴
素
考
虑
[
1
−
n
]
的
约
数
个
数
的
和
。
也
就
是
考
虑
每
个
约
数
的
贡
献
(
出
现
了
多
少
次
)
朴素考虑 [1-n]的约数个数的和。也就是考虑每个约数的贡献(出现了多少次)
朴素考虑[1−n]的约数个数的和。也就是考虑每个约数的贡献(出现了多少次)
枚
举
每
一
个
约
数
i
其
出
现
了
⌊
n
i
⌋
次
枚举每一个约数 i 其出现了 \lfloor{\frac{n}{i}}\rfloor 次
枚举每一个约数i其出现了⌊in⌋次
于
是
答
案
a
n
s
=
∑
i
=
1
n
⌊
n
i
⌋
于是答案 ans = \sum^{n}_{i=1} \lfloor{\frac{n}{i}}\rfloor
于是答案ans=∑i=1n⌊in⌋
但
是
n
为
1
e
9
显
然
枚
举
是
会
超
时
的
但是 n 为 1e9 显然枚举是会超时的
但是n为1e9显然枚举是会超时的
我
们
考
虑
一
个
定
理
⌊
n
i
⌋
的
取
值
只
有
n
种
我们 考虑一个定理 \lfloor{\frac{n}{i}}\rfloor的取值只有 \sqrt n 种
我们考虑一个定理⌊in⌋的取值只有n种
也
就
是
说
对
于
不
同
的
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,⌊⌊in⌋n⌋]
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 出现的次数 因数i⌊in⌋出现的区间⌊in⌋出现的次数
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;
}