链接:LightOJ - 1245 Harmonic Number (II)
题意:
给出 T ( ≤ 1000 ) T(\le1000) T(≤1000)个 n ( 1 ≤ n ≤ 2 31 ) n(1\le n\le2^{31}) n(1≤n≤231),每次求解 H ( n ) = ⌊ n 1 ⌋ + ⌊ n 2 ⌋ + ⋯ + ⌊ n n ⌋ H(n)=\lfloor \frac{n}{1}\rfloor+\lfloor\frac{n}{2}\rfloor+\dots+\lfloor\frac{n}{n}\rfloor H(n)=⌊1n⌋+⌊2n⌋+⋯+⌊nn⌋
分析:
对于 ⌊ n i ⌋ \lfloor \frac{n}{i}\rfloor ⌊in⌋求和,实际上 ⌊ n i ⌋ \lfloor \frac{n}{i}\rfloor ⌊in⌋只有至多 ⌊ 2 n ⌋ \lfloor 2\sqrt n\rfloor ⌊2n⌋种取值。
对于任意
i
≤
n
i\le n
i≤n,需要找到一个最大的
j
≤
n
j\le n
j≤n,使得
⌊
n
i
⌋
=
⌊
n
j
⌋
\lfloor \frac{n}{i}\rfloor=\lfloor \frac{n}{j}\rfloor
⌊in⌋=⌊jn⌋,则有:
j
=
⌊
n
⌊
n
i
⌋
⌋
j=\left\lfloor \frac{n}{\lfloor \frac{n}{i}\rfloor}\right \rfloor
j=⌊⌊in⌋n⌋
所以当从小到大枚举 i i i,则 ⌊ n i ⌋ \lfloor \frac{n}{i}\rfloor ⌊in⌋的个数为 j − i + 1 j-i+1 j−i+1个,求和的时间复杂度为 O ( ⌊ 2 n ⌋ ) O(\lfloor 2\sqrt n\rfloor) O(⌊2n⌋)。
以下代码:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int main()
{
int T,kase=0;
scanf("%d",&T);
LL n;
while(T--)
{
scanf("%lld",&n);
LL i=1,j,ans=0;
while(i<=n)
{
j=n/(n/i);
ans+=(n/i)*(j-i+1);
i=j+1;
}
printf("Case %d: %lld\n",++kase,ans);
}
return 0;
}