Notice
Recent Posts
Link
정화 코딩
[C++] Σ (백준 13172번) 본문
https://www.acmicpc.net/problem/13172
이 문제의 핵심을 정리하면 아래와 같다.
기약분수 a/b를 다음과 같이 하나의 정수로 표현할 수 있다.
이 때 X는 1,000,000,007과 같은 큰 소수이다.
b^(-1)은 b의 모듈러 곱셈에 대한 역원인데, 다음과 같이 계산할 수 있다.
이 정도만 알면 문제를 풀 수 있다.
이제 구체적으로 어떻게 구현할지 생각해보자.
한 줄에 분모와 분자 순서대로 한 쌍의 분수가 들어온다. 각 분수에 대해 a * b^(-1) mod X 를 구하면 된다. 그리고 모든 값들을 마치 확률을 더하듯 그냥 더해주면 된다.
내가 헷갈렸던 점은 기약분수 a/b에 대해서 저렇게 계산해야 된다고 하길래 들어온 분모와 분자에 대해서 우선 기약분수 형태로 만들어줘야 하나 했었다. 그런데 굳이 그런 처리는 안 해주어도 된다.
(그리고 분모 분자 순서 반대로 받아서 20분 삽질함...)
그래서 분할 정복으로 거듭 제곱하는 함수 하나만 구현해주고 mod 주의해서 계산만 하면 끝~~
#include <iostream>
#include <vector>
using namespace std;
int MOD = 1000000007;
long long sq(long long x, long long n) {
if (n == 0) return 1;
long long tmp = sq(x , n / 2) % MOD;
if (n % 2 == 0) return (tmp * tmp) % MOD;
else return (((tmp * tmp) % MOD) * x) % MOD;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int m;
cin >> m;
int ans = 0;
for (int i = 0; i < m; i++) {
long long a, b;
cin >> b >> a;
int tmp = (a * sq(b, MOD - 2)) % MOD;
ans = (ans + tmp) % MOD;
}
cout << ans << '\n';
}
(AC)
'PS' 카테고리의 다른 글
[C++] 초콜릿과 11과 팰린드롬 (백준 31460번) (0) | 2025.03.24 |
---|---|
[C++] 포항항 (백준 23817번) (0) | 2025.03.22 |
[C++] 숨바꼭질 2 (백준 12851번) (0) | 2025.03.18 |
[C++] 중앙값 제거 (백준 23758번) (0) | 2025.03.17 |
[C++] 주식 (백준 11501번) (0) | 2025.03.15 |
Comments