반응형
(A + B) % C = ((A % C) + (B % C)) % C |
(A - B) % C = ((A % C) - (B % C)) % C |
(A * B) % C = ((A % C) * (B % C))) % C |
모듈러 연산 (더 알고싶으면 유클리드 호제법 검색하기.)
이를 이용하여
(A1 * A2 * ... * An) % C |
(A1 * A2 * .. * An) 을 다 계산하게 되면 수가 매우 커지게 되며 시간복잡도 또한 O(n) 이 되게 된다.
따라서 우리는 위와 같이 모듈러 연산을 사용하면 시간복잡도 및 연산의 결과가 자료형의 크기를 벗어나며 오류가 나는 상황을 막을 수 있다.
((A1 * A2 * A3 * ... * An-1) % C * (An % C)) % C |
너무 안예쁜데..
훔..
위와 같은 모듈러 연산을 분할을 통해 계산을 하면 된다.
완전이진트리, 퀵소트와 같이 절반씩 잘라가면서 수행하는 연산이 제일 속도가 빠르므로
나누기 2를 하며 홀수가 나오면 a를 한번 더 곱해준 상황에서 연산을 하게 로직을 구현했다.
또한 result에 내용을 넣어서 처리하면 어짜피 마지막 b=1 일 때 걸리기 때문에 같이 넣어서 구현했다.
백준 1629번 소스코드이다.
#include <iostream> #include <stdio.h> #include <vector> #include <string> #include <algorithm> using namespace std; long long result = 1; long long divide(long long a, long long b, long long c) { a %= c; // 2,147,483,647를 한번이라도 곱하는 순간 범위 초과하지않아..? // 모듈러 연산에 의해 나머지를 구하기 위해서 나머지를 사용해도 결과는 같음. while (b>0) { // b가 1일 때 즉 제일 밑단에 있는 친구가 등장 할 때 result에 곱하고 나누면서 결과 확인 if(b%2==1) { // b가 홀수일 경우에는 /2 한거에 *를 한번 더 해줘야 하기 때문. result *= a; result %= c; } a = ((a%c) * (a%c)) %c; b /=2; } return result; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); long long A,B,C; cin >> A >> B >> C; cout << divide(A, B, C);; return 0; } |
반응형
'C++' 카테고리의 다른 글
DFS 기초 코드 (0) | 2022.02.26 |
---|---|
C++ 에서 원주율 π / 자연상수 e 와 같은 무리수를 표시하기. (0) | 2022.02.05 |