题意
求 n/1+n/2+..n/n n / 1 + n / 2 + . . n / n
分析
分块
求 n/k = t 的k的个数
[nk]>=t
[
n
k
]
>=
t
的个数为
[nt]
[
n
t
]
个,于是
[nk]=t
[
n
k
]
=
t
的个数就是
[nt]−[nt+1]
[
n
t
]
−
[
n
t
+
1
]
证明如下
n/k>=[n/k]>=t
n
/
k
>=
[
n
/
k
]
>=
t
∵t∗k<=n
∵
t
∗
k
<=
n
∴t<=n/k
∴
t
<=
n
/
k
又
∵t∗[n/t]<=n
∵
t
∗
[
n
/
t
]
<=
n
于是
kmax=[n/t]
k
m
a
x
=
[
n
/
t
]
问题得证
参考代码
#include <iostream>//c++IO
#include <cmath>
#include <cstdio>
using namespace std;
int main(void)
{
std::ios::sync_with_stdio(false);
int T;
cin>>T;
int Kase = 0;
while(T--)
{
long long n;
cin>>n;
int m = (int)sqrt(n);
long long ans = 0;
for(long long i = 1;i < m; ++i)
{
ans += n/i;
ans += (long long )i*(n/i - n/(i+1));
}
ans += n/m;
ans += m*(n/m-m);//注意要加上等于n/k = m的情况,但如果k < m 这种情况已经计算过了
printf("Case %d: %lld\n",++Kase,ans);
}
return 0;
}
//......................................................
int main(void)
{
//std::ios::sync_with_stdio(false);
int T;
scanf("%d",&T);
int Kase = 0;
while(T--)
{
LL n;
scanf("%lld",&n);
LL ans = 0;
for(LL i = 1;i <= n; ){
ans += (n/(n/i)-i+1)*(n/i);
i = n/(n/i)+1;
}
printf("Case %d: %lld\n",++Kase,ans);
}
return 0;
}