其他分享
首页 > 其他分享> > 1103上午考试T1

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

标签:ch,正整数,....,long,T1,枚举,1103,考试
来源: https://www.cnblogs.com/czhui666/p/13929696.html