CF 729 C

cf 729 C

[link] <Problem - C - Codeforces>

题意

f(k) == x , 找到和k最小互质的数x, 输入一个n,求1 到 n中f(k)的和

题解

1 到 n中能被x整除的数由多少个 ?

x的倍数 均可被整除

n / x == d //最多到x的d倍

x, 2x, 3x, …… , dx 均成立,故有d个

lcm:最小公倍数,一堆数的最小基元

gcd:最大公约数,两数的最大交集

gcd(a, b) = d, lcm (a, b) = a * b / d

f(k) = x 等价于 (1,2 …, x - 1) | k

A = n / lcm(1 – x - 1) f(k) 至少是x的数

B = n / lcm(1 – x ) f(k) 至少是x + 1 的数

f(k) = x 的所有数就是 A - B

贡献是i的数在贡献是i - 1的时候贡献了i - 1所以只需要一个叠加,找到贡献为i的数每一个贡献都是1即可

f(k) = x 中 x一定是 1 2 3 4 5 … 递增出现的

枚举到i,则至少为i的数目为n / lcm(1,2 ……, i - 1).

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <set>
#include <queue>
#include <vector>
#include <map>
#include <unordered_map>
#include <cmath> 
#include <stack>
#define x first
#define y second
 
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
const int N = 2e5 + 10, M = 1100, INF = 0x3f3f3f3f, P = 131;
const LL mod = 1e9 + 7;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int n, m, k; 
int dist[N];
int last[N]; 
bool st[N];
LL gcd(LL a, LL b) {
	return b ? gcd(b, a % b) : a;
}
LL lcm(LL a, LL b) {
	return a * b / gcd(a, b); 
}
int main (){ 
	int t;
	cin >> t;
	while (t --) {
		LL n;
		cin >> n;
		int res = 0;
		for (LL x = 1, i = 1; x <= n; x = lcm(x, i), i ++ )
			res = (res + n / x) % mod;
		cout << res << endl;
	} 
	return 0;
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值