不会类欧的可以看这里
枚举 (x),那么合法的 (y) 的个数为 (lfloor dfrac{c - ax}{b} floor+1)。那么题目要求的就是:
[sum_{x=0}^{lfloor frac{c}{a}
floor} lfloor frac{c-ax}b
floor+1
]
发现和类欧的唯一区别是 (x) 的系数是负数。但是我们可以在分子上加一个 (bx) 即可。这里假设 (b ge a),当 (b < a) 的时候可以交换 (a,b)。
[egin{aligned}
sum_{x=0}^{lfloor frac{c}{a}
floor} lfloor frac{(b-a)x+c}{b}
floor - x + 1\
= sum_{x=0}^{lfloor frac{c}{a}
floor} lfloor frac{(b-a)x+c}b
floor - frac{lfloor frac{c}{a}
floor (lfloor frac{c}{a}
floor + 1)}2+lfloor frac{c}{a}
floor + 1
end{aligned}
]
然后直接用类欧算即可。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
typedef long long ll;
template <typename T> inline void read(T &x) {
x = 0; char c = getchar(); bool flag = false;
while (!isdigit(c)) { if (c == '-') flag = true; c = getchar(); }
while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); }
if (flag) x = -x;
}
using namespace std;
inline ll sol(ll a, ll b, ll c, ll n) {
if (!a) return (n + 1) * (b / c);
if (a >= c || b >= c) {
return n * (n + 1) / 2 * (a / c) + (n + 1) * (b / c) + sol(a % c, b % c, c, n);
}
ll m = (a * n + b) / c;
return n * m - sol(c, c - b - 1, a, m - 1);
}
int main() {
ll a, b, c; read(a), read(b), read(c);
if (b < a) swap(b, a);
ll res = 0;
res += sol(b - a, c, b, c / a);
res -= (c / a) * (c / a + 1) / 2;
res += c / a;
++res;
cout << res << endl;
return 0;
}