Strange Function

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;
}

你可能感兴趣的:(codeforces补题,蓝桥杯,c++,acm竞赛,算法)