LightOJ - 1245 Harmonic Number (II) (找規律)
阿新 • • 發佈:2018-08-12
can 時間復雜度 += splay info code sqrt class .com
題目大意:給出一個n(1 <= n < 2^31)求出H(n)的結果,H(n)的定義為下:
分析:對於一個n,設 t = n / i:
滿足 t >= 1的有多少個呢? 有 n / 1 個。
滿足 t >= 2的有多少個呢? 有 n / 2 個。
……
滿足 t >= k的有多少個呢? 有 n / k 個。
以上結論不難發現,我們再進一步就能發現:
滿足 t == 1 的有 n/1 - n/2 個
滿足 t == 2 的有 n/2 - n/3 個
……
滿足 t == k 的有 n/k - n/(k+1) 個
發現這個規律,我們就需要考慮這個 t 枚舉到哪呢?t 從1 枚舉 到 n 肯定是對的,但是時間上不允許,我們可以改進一下,我們在枚舉 t >= i 的時候,我們可以順便計算出滿足 t >= n/i 的有多少個(舉個例子,n == 10,t >= 2的有5個,那麽t>=5的就有2個)。這樣一來時間復雜度就變為O(√n)了,這樣就足夠了。詳情見代碼:
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cmath> 5 using namespace std; 6 7 typedef long long LL; 8 typedef unsigned long long ULL; 9 10 LL H(int n){ 11 LL ans = 0; 12 int m = sqrt(n+0.5); 13 for(int i = 2; i <= m; ++i){View Code14 ans += (LL)(i-1)*(n/(i-1)-n/i); 15 ans += n/(i-1); 16 } 17 ans += m*(n/m - m); 18 ans += n/m; 19 return ans; 20 } 21 22 int main(){ 23 int T, ca = 1; 24 scanf("%d", &T); 25 while(T--){ 26 int n; 27 scanf("%d", &n); 28 printf("Case %d: %lld\n", ca++, H(n)); 29 } 30 return 0; 31 }
LightOJ - 1245 Harmonic Number (II) (找規律)