블로그 옮겼습니다
UVa OJ 12775 - Gift Dilemma 본문
https://uva.onlinejudge.org/external/127/12775.pdf
\(0 < A, B, C, P < 10^8\)
\(C / gcd(A, B, C) >= 200\)
일 때,
Ax + By + Cz = P
위의 디오판토스 방정식의 음이 아닌 정수 해 (x, y, z) 의 개수를 구하는 문제이다.
우선 위에서 주어진 두 조건 중 두번째 조건을 주목하자. C / gcd(A, B, C) 가 200이상이라는 말은 일단
적어도 입력으로 들어오는 C가 200이상이라는 것을 알 수 있다. 그러면 z를 고정시키고 그에 대한 (x, y) 를 구하는
식으로 계산한다치면, 최악의 경우에도 고정하는 z의 개수는 10^8 / 200 이하, 즉 50만개 이하가 된다.
그럼 z를 고정시키고 x, y 를 구해보자. 만약 z가 정해지면 오른쪽 항으로 넘겨서
Ax + By = P'
의 형태를 만들 수가 있다.
그럼 확장 유클리드로 특수해를 하나 구한 뒤, 전체 해의 양쪽 경계를 O(1) 에 계산하여
전체 개수를 구하는 식으로 답에 누적해나가면 된다.
시간복잡도는 O((L/C)lgL) ( 0 < L < 10^8, 200 <= C < L)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #include <bits/stdc++.h> #define fastio() ios_base::sync_with_stdio(0),cin.tie(0) using namespace std; typedef long long ll; const int mod = 1e9+7; const int INF = 0x3c3c3c3c; const long long INFL = 0x3c3c3c3c3c3c3c3c; ll trash; ll xGCD(ll a, ll b, ll& x, ll& y){ if(!b){ x = 1, y = 0; return a; } ll x1, y1; ll ret = xGCD(b, a % b, x1, y1); x = y1, y = x1 - (a / b) * y1; return ret; } ll findRng(ll x0, ll y0, ll a, ll b){ if(y0 <= 0) { swap(x0, y0); swap(a, b); } ll g = xGCD(a, b, trash, trash); ll dx = b / g, dy = - a / g; ll t1, t2; if(x0 < 0) t1 = (-x0 + dx - 1) / dx; else t1 = 0; t2 = y0 / (-dy); return max(0ll, t2 - t1 + 1); } ll T, A, B, C, P; ll a, b, p; int main() { fastio(); cin >> T; for(ll t = 1; t <= T; t++){ cout << "Case " << t << ": "; cin >> A >> B >> C >> P; ll ans = 0; for(int i = 0 ; i * C < P; i++){ ll p = P - i * C; ll g = xGCD(xGCD(A, B, trash, trash), p, trash, trash); a = A / g, b = B / g, p /= g; ll x, y; ll gg = xGCD(a, b, x, y); if(gg != 1) continue; ans += findRng(x * p, y * p, a, b); } if(P % C == 0) ans++; cout << ans << endl; } return 0; } | cs |
'Algorithm > Problem Solving' 카테고리의 다른 글
Topcoder SRM 533 Div1(Easy) CasketOfStar (0) | 2017.07.25 |
---|---|
BOJ 14657번 준오는 최종 인재야!! (0) | 2017.07.23 |
BOJ 9169번 나는 9999번 문제를 풀 수 있다 (0) | 2017.07.15 |
BOJ 2365번 숫자판 만들기 (0) | 2017.07.14 |
Topcoder SRM 527 Div1(Easy) P8XGraphBuilder (0) | 2017.07.14 |
Comments