Let f(i)f(i) denote the minimum positive integer xx such that xx is not a divisor of ii.
Compute ∑ni=1f(i)∑i=1nf(i) modulo 109+7109+7. In other words, compute f(1)+f(2)+⋯+f(n)f(1)+f(2)+⋯+f(n) modulo 109+7109+7.
Input
The first line contains a single integer tt (1≤t≤1041≤t≤104), the number of test cases. Then tt cases follow.
The only line of each test case contains a single integer nn (1≤n≤10161≤n≤1016).
Output
For each test case, output a single integer ansans, where ans=∑ni=1f(i)ans=∑i=1nf(i) modulo 109+7109+7.
Input:
6
1
2
3
4
10
10000000000000000
Out:
2
5
7
10
26
366580019
题意:给一个n,我们要求f(1) + f(2) + ……+f(n)。其中f[x]等于不被x整除的大于1的最小整数。
思路:我们假设n = 10,ans = f(1) + f(2)+ ……+f(10)。其中能被2整除的是{2,4,6,8,10},能被2整除的数为n/2,而其他的都不被x整除的大于1的最小整数就是2,即有sum - n / 2 个答案是2,我们只要把这个数乘以2给答案加上即可,此时剩余的可以选的数为n/2个,即那些能被2整除的数。即让sum = n/2;
到了三也是类似。我们现在就是要求是二的倍数,但不是3的倍数的数,这样的数答案就是3,现在剩余集合{2,4,6,8,10},全都是2的倍数,同时又是3的倍数的是{6},当我们如果仍然用n / 3结果是,能被3整除的结果是{3,6,9}但是其中3,9已经被用过了,因此我们要找的是n/lcm(3,2)的个数。这样就只有一个6既是2的倍数又是3的倍数,而剩余集合中又全都是2的倍数,因此sum - n/lcm(3,2) = 5 - 1 = 4,即4个答案都是3.最后集合只剩下{6},即sum = n/lcm(3,2)
如果n更大的话,我们只要保证集合剩余的都是2,3,4……等的倍数即可。
AC代码:
#include
#define int long long
#define rep(i, a, b) for(int i = a; i <= b; i ++)
using namespace std;
const int mod = 1e9 + 7;
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int lcm(int a,int b){
return a / gcd(a,b) * b;
}
void solve(){
int n; cin >> n;
int ans = 0,x = 1;
int sum = n;
for(int i = 2;;i++){
int lc = lcm(x,i);
int cnt = n / lc;// 能被最大公倍数整除的个数 ,也是下次集合可以选的数。
// cout << cnt << endl;
ans += (sum - cnt)*i; // sum- cnt个数f是i
sum = cnt;
if(sum == 0) break;
x = lc;
}
cout << ans%mod << endl;
}
signed main()
{
int _; cin >>_;
while(_--){
solve();
}
return 0;
}