題目:計算Σn/i,其中i取1到n(對應的除法為整數除法)。
分析:數學,公式,找規律。如果直接計算顯然會超時,所以找規律。
我們首先將數據分成不同的區間,n/i為n,n/i為n/2,...,n/i為1;
可以看出,有n/2的數據使得n/i值為1;
可以看出,有n/2 - n/3的數據使得n/i值為2;
...
因此得到計算方法:ans = Σ(i * (n/i - n/(i+1)));其中n取1到n;(這計算量並沒有變化)
設m為不超過n平方根的最大整數;
我們發現i不大於m時時連續變化的,大於m之後就不是連續變化的了;(可以證明)
因此只計算1到m的值,剩餘的值只有n/(m+1)個,直接用n除加和即可;
因此時間複雜度為O(sqrt(n));
說明:數據中有0,注意RE。見到有人推出公式:2*Σ(n/i) - n*n,其中i取1到sqrt(n)。
#include <stdio.h>
#include <math.h>
long long H(int n)
{
long long ans = 0;
int m = (int)sqrt(0.0+n);
// 計算大於平方根部分(含等於)
for (int i = 1; i <= m; ++ i) {
ans += i*(n/i - n/(i+1));
}
// 計算小於平方根部分
for (int i = n/(m+1); i >= 1; -- i) {
ans += n/i;
}
return ans;
}
int main()
{
int T, n;
while (~scanf("%d",&T))
while (T --) {
scanf("%d",&n);
printf("%lld\n",H(n));
}
return 0;
}