-
[12971] 숫자 놀이BOJ 2022. 8. 11. 00:21
https://www.acmicpc.net/problem/12971
12971번: 숫자 놀이
공백으로 구분된 6개의 정수 P1, P2, P3, X1, X2, X3가 순서대로 주어진다. 모든 숫자는 1과 300사이의 정수다.
www.acmicpc.net
중국인의 나머지 정리
#include <bits/stdc++.h>using namespace std;#ifdef ONLINE_JUDGEconstexpr bool local = false;#elseconstexpr bool local = true;#endifusing ll = long long;using pi = pair<ll, ll>;ll minv(ll a, ll b) {if (a == 0 && b == 1) return 0;if (a == 1) return 1;return b - minv(b % a, a) * b / a;}
// x == A.first (mod A.second)// x == B.first (mod B.second)// returns solution as X == ans.first (mod ans.second)// if no solution, returns (-1, -1)// always a good idea to keep 0 <= ?.first < ?.second (for ? : A, B, ans)pair<ll, ll> crt(pair<ll, ll> A, pair<ll, ll> B) {if (A.second == -1 || B.second == -1) return make_pair(-1, -1);if (A.second == 1) return B;if (B.second == 1) return A;ll g = gcd(A.second, B.second); // gcdll l = A.second * (B.second / g); // lcmif ((B.first - A.first) % g != 0)return make_pair(-1, -1); // no solution case
ll a = A.second / g;ll b = B.second / g;ll mul = (B.first - A.first) / g;mul = (mul * minv(a % b, b)) % b; // this is now tll ret = (mul * A.second + A.first); // n_1 t + a_1ret %= l;ret = (ret + l) % l; // take modulosreturn make_pair(ret, l);}int main(void) {if (!local) ios_base::sync_with_stdio(0), cin.tie(0);ll p1, p2, p3, x1, x2, x3;cin >> p1 >> p2 >> p3 >> x1 >> x2 >> x3;// N==x1(mod p1)// N==x2(mod p2)// N==x3(mod p3)
auto f = crt({x1, p1}, {x2, p2});auto g = crt({f.first, f.second}, {x3, p3});if (f.first == -1 or g.first == -1) {cout << -1;return 0;}if (0 < g.first and g.first < 1'000'000'000)cout << g.first;elsecout << -1;return 0;}
'BOJ' 카테고리의 다른 글
[14653] 너의 이름은 (0) 2023.03.02 [11493] 동전 교환 (1) 2022.11.23 [10775] 공항 (0) 2022.08.02 lazy 세그 - 비재귀 (0) 2022.07.26 [10999] 구간 합 구하기 2 (0) 2022.07.26