#include #include #include #include #include #include #include #include namespace nono { template class CSRArray { using iterator = std::vector::iterator; using const_iterator = std::vector::const_iterator; using subrange = std::ranges::subrange; using const_subrange = std::ranges::subrange; public: CSRArray() = default; CSRArray(int row_size, const std::vector>& data) : row_size_(row_size), indptr_(row_size_ + 1), data_(data.size()) { for (auto key: data | std::views::keys) { indptr_[key + 1]++; } for (int i = 0; i < row_size_; i++) { indptr_[i + 1] += indptr_[i]; } auto index = indptr_; for (const auto& [key, value]: data) { data_[index[key]++] = value; } } CSRArray(int row_size, const std::vector& row, const std::vector& data) : row_size_(row_size), indptr_(row_size_ + 1), data_(data.size()) { for (auto key: row) { indptr_[key + 1]++; } for (int i = 0; i < row_size_; i++) { indptr_[i + 1] += indptr_[i]; } auto index = indptr_; for (int i = 0; i < (int)data.size(); i++) { data_[index[row[i]]++] = data[i]; } } subrange operator[](int i) { return std::ranges::subrange(data_.begin() + indptr_[i], data_.begin() + indptr_[i + 1]); } const_subrange operator[](int i) const { return std::ranges::subrange(data_.begin() + indptr_[i], data_.begin() + indptr_[i + 1]); } int all_size() const { return data_.size(); } int size() const { return row_size_; } private: int row_size_; std::vector indptr_; std::vector data_; }; } // namespace nono #include #include #include namespace nono { template struct EdgeBase { int from; int to; T weight; EdgeBase() {} EdgeBase(int from, int to, T weight = 1): from(from), to(to), weight(weight) {} }; using Edge = EdgeBase; template using WeightedEdge = EdgeBase; template class Graph { struct Edge_ { int to; T weight; int id; }; using iterator = std::vector::iterator; using const_iterator = std::vector::const_iterator; using subrange = std::ranges::subrange; using const_subrange = std::ranges::subrange; public: template friend Graph to_undirected_graph(int n, const std::vector>& edges); template friend Graph to_directed_graph(int n, const std::vector>& edges); subrange operator[](int i) { return std::ranges::subrange(edges_.begin() + indptr_[i], edges_.begin() + indptr_[i + 1]); } const_subrange operator[](int i) const { return std::ranges::subrange(edges_.begin() + indptr_[i], edges_.begin() + indptr_[i + 1]); } int size() const { return n_; } int edge_size() const { return m_; } bool is_directed() const { return directed_; } bool is_undirected() const { return !is_directed(); } private: Graph(int n, const std::vector>& edges, bool directed) : n_(n), m_(edges.size()), indptr_(n_ + 1), edges_(directed ? edges.size() : 2 * edges.size()), directed_(directed) { for (const auto& e: edges) { indptr_[e.from + 1]++; if (!directed_) indptr_[e.to + 1]++; } for (int i = 0; i < n_; i++) { indptr_[i + 1] += indptr_[i]; } auto index = indptr_; for (int i = 0; i < std::ssize(edges); i++) { const auto& e = edges[i]; edges_[index[e.from]++] = Edge_(e.to, e.weight, i); if (!directed_) edges_[index[e.to]++] = Edge_(e.from, e.weight, i); } } int n_; int m_; std::vector indptr_; std::vector edges_; bool directed_; }; template Graph to_undirected_graph(int n, const std::vector>& edges) { return Graph(n, edges, false); } template Graph to_directed_graph(int n, const std::vector>& edges) { return Graph(n, edges, true); } } // namespace nono #include namespace nono { template bool is_bipartite(const Graph& graph) { int n = graph.size(); std::vector color(n, -1); auto dfs = [&](auto&& self, int u) -> bool { for (auto e: graph[u]) { if (color[e.to] == -1) { color[e.to] = color[u] ^ 1; if (!self(self, e.to)) return false; } else if (color[e.to] == color[u]) { return false; } } return true; }; for (int i = 0; i < n; i++) { if (color[i] == -1) { color[i] = 0; if (!dfs(dfs, i)) return false; } } return true; } } // namespace nono namespace nono { std::vector bipartite_matching(int left, int right, std::vector> edges) { int m = edges.size(); for (auto& [u, v]: edges) { v += left; } const CSRArray graph(left, edges); const int inf = std::numeric_limits::max(); std::vector adj(left + right, -1); std::vector dist(left + right, inf); std::queue que; while (true) { std::fill(dist.begin(), dist.end(), inf); for (int i = 0; i < left; i++) { if (adj[i] == -1) { dist[i] = 0; que.push(i); } } while (!que.empty()) { int u = que.front(); que.pop(); for (auto v: graph[u]) { if (dist[v] == inf && adj[u] != v) { dist[v] = dist[u] + 1; if (adj[v] != -1) { dist[adj[v]] = dist[v] + 1; que.push(adj[v]); } } } } bool reached = false; for (int i = left; i < left + right; i++) { reached |= dist[i] != inf && adj[i] == -1; } if (!reached) break; auto dfs = [&](auto&& self, int u) -> bool { for (auto v: graph[u]) { if (dist[u] + 1 == dist[v]) { dist[v] = inf; if (adj[v] == -1 || self(self, adj[v])) { adj[u] = v; adj[v] = u; return true; } } } return false; }; for (int i = 0; i < left; i++) { if (adj[i] == -1) { dfs(dfs, i); } } } std::vector result; for (int i = 0; i < m; i++) { auto [u, v] = edges[i]; if (adj[u] == v) { result.push_back(i); adj[u] = -1; } } return result; } template std::vector bipartite_matching(const Graph& graph) { int n = graph.size(); int m = graph.edge_size(); std::vector mapping(n, -1); std::vector is_lefts(n); int left = 0, right = 0; auto dfs = [&](auto&& self, int u, bool is_left = true) -> void { is_lefts[u] = is_left; if (is_left) { mapping[u] = left++; } else { mapping[u] = right++; } for (auto e: graph[u]) { if (mapping[e.to] == -1) { self(self, e.to, is_left ^ true); } } }; for (int i = 0; i < n; i++) { if (mapping[i] == -1) { dfs(dfs, i); } } std::vector> edges(m); for (int u = 0; u < n; u++) { if (!is_lefts[u]) continue; for (auto e: graph[u]) { edges[e.id] = {mapping[u], mapping[e.to]}; } } return bipartite_matching(left, right, edges); } } // namespace nono #include using namespace std; using ll = long long; using ld = long double; using ull = unsigned long long; template using max_heap = priority_queue; template using min_heap = priority_queue, greater>; #define rep(i, l, r) for (ll i = (l); i < (r); i++) #define rrep(i, r, l) for (ll i = (r); i-- > (l);) #define all(x) begin(x), end(x) template bool chmin(T& lhs, T rhs) { return lhs > rhs ? (lhs = rhs, true) : false; } template bool chmax(T& lhs, T rhs) { return lhs < rhs ? (lhs = rhs, true) : false; } struct IOIO { IOIO() { cin.tie(0)->sync_with_stdio(0); } } ioio; template ostream& operator<<(ostream& os, const pair& p) { os << '(' << p.first << ", " << p.second << ')'; return os; } template ostream& operator<<(ostream& os, const vector& vs) { os << '{'; rep(i, 0, (int)vs.size()) os << vs[i] << (i + 1 == (int)vs.size() ? "" : ", "); os << '}'; return os; } template ostream& operator<<(ostream& os, const set& vs) { os << '{'; for (auto it = vs.begin(); it != vs.end(); it++) { if (it != vs.begin()) { os << ", "; } os << *it; } os << '}'; return os; } template ostream& operator<<(ostream& os, const map& vs) { os << '{'; for (auto it = vs.begin(); it != vs.end(); it++) { if (it != vs.begin()) { os << ", "; } os << *it; } os << '}'; return os; } #ifdef DEBUG void dump_func() { cerr << endl; } template void dump_func(Head&& head, Tail&&... tail) { cerr << head; if (sizeof...(Tail) > 0) { cerr << ", "; } dump_func(std::move(tail)...); } #define dump(...) cerr << "[" + string(#__VA_ARGS__) + "] ", dump_func(__VA_ARGS__) #else #define dump(...) static_cast(0) #endif void solve() { ll d, x, y; cin >> d >> x >> y; ll ans = 0; auto F = [&](ll a) { return -((x * (a - x)) / y) + y; }; auto area = [&](ll x1, ll y1, ll x2, ll y2) { return abs((x1 * y2) - (x2 * y1)); }; auto in = [&](ll v) { return 0 <= v && v <= d; }; { ll g = y / gcd(y, x); ll ok = 0; ll ng = (d + g) / g; while (ng - ok > 1) { ll key = (ok + ng) / 2; if (in(g * key + x) && in(F(g * key + x))) ok = key; else ng = key; } chmax(ans, area(x, y, g * ok + x, F(g * ok + x))); } { ll g = y / gcd(y, x); ll ok = 0; ll ng = -((x + g) / g); while (ok - ng > 1) { ll key = (ok + ng) / 2; if (in(g * key + x) && in(F(g * key + x))) ok = key; else ng = key; } chmax(ans, area(x, y, g * ok + x, F(g * ok + x))); } cout << ans << '\n'; } int main() { int t; cin >> t; while (t--) solve(); }