1103上午考试T1

1103晚上考试T1

T1

​ 题目大意:

​ 对于给定正整数 n,m,我们称正整数 c 为好的,当且仅当存在非负整数 x,y,使得 nx+my=c。现在给出多组数据,对于每组数据,给定 n,m,q,求[1,q]内有多少个正整数不是好的。 \(n <= 1e5, m <= 1e9, q <= 1e18\);

​ 对于\(x, y\)都不确定的情况下,我们可以枚举一个,去算另一个.

​ 首先原式可化为:\(x = \frac{c - my}{n}\),我们枚举y,然后找一找规律.

​ 假定\(n = 2, m = 3\).

​ 当\(y = 0\)时,合法的\(c\)有2, 4, 6, 8, 10....

​ 当\(y = 1\)时,合法的\(c\)有3, 5, 7, 9, 11....

​ 当\(y = 2\)时,合法的\(c\)有6, 8, 10, 12....

然后我们发现重复了,多举几个例子,我们发现在\(lcm(n, m)\)的时候会重复,所以我们只需枚举到\(min(lcm(n, m), q) / n\)就可以找出所有结果,这么写的复杂度是正确的.

​ 答案的话直接用总数\(q\)减去合法的就好了.

#include <bits/stdc++.h>

using namespace std;

inline long long read() {
	long long s = 0, f = 1; char ch;
	while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
	for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
	return s * f;
}

long long n, m, q, ans;

long long gcd(long long x, long long y) {
	return y == 0 ? x : gcd(y, x % y);
}

int main() {
	
	for(int T = read(); T ; T --) {
		n = read(); m = read(); q = read(); ans = 0;
		long long lca = n * m / gcd(n, m); lca --; //这里注意要减一
		for(int i = 0;i <= min(lca, q) / m; i++) 
			ans += (q - i * m) / n + 1;
		printf("%lld\n", q - ans + 1);
	}
	
	return 0;
}
posted @ 2020-11-05 06:22  C锥  阅读(104)  评论(0编辑  收藏  举报