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