Write a program to compute the following sum S given a positive integer n:
, where is the largest integer not greater than x.
The input file consists of several datasets. The first line of the input file contains the number of datasets which is a positive integer and is not greater than 30. The following lines describe the datasets.
Each dataset contains a positive integer n (n ≤ 1012) written on a separate line.
For each dataset, write in one line the remainder of the computed sum S divided by 106.
2 1 5
1 10
题意就是计算S, 由于n可以10^12, O(n)不能解决。可以用一种O(sqrt n)的算法。
计算当前的n/i之后 假设值为v, 那么n/v一定是大于等于i的一个整数 而且在i到n/v这些下标 值都应该是v。从而不需要计算每个i的值。可以证明只需要O(sqrt n) 次。
下面证明:
假设i = sqrt n,那么之前最多遍历sqrt n个下标,关键看之后是不是也是遍历不会超过sqrt n个。
假设 i >= sqrt n, 那么n/i的最大值就是sqrt n 由于v不会重复, 那么最多算sqrt n次。
总共2 * sqrt n ,所以复杂度为O(sqrt n)
#include <cstdio>
#include <string>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 21000000
#define mod 1000000
typedef __int64 LL;
const int MAX = 0x3f3f3f3f;
LL n;
int T;
int main() {
cin>>T;while(T--) {
cin >> n;
LL i = 1, ans = 0;
while(i <= n) {
LL v = n / i;
LL last = n / v;
ans += v * (last - i + 1);
ans %= mod;
i = last + 1;
}
cout << ans << endl;
}
return 0;
}