일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Coroutine
- MiTweet
- Kotlin
- AWS
- android
- 프로그래머스
- boj
- 코루틴
- TEST
- Codeforces
- 쿠링
- MyVoca
- Hilt
- 백준
- livedata
- Python
- 암호학
- Compose
- activity
- relay
- Rxjava
- pandas
- Gradle
- Coroutines
- ProGuard
- androidStudio
- architecture
- textfield
- 코드포스
- GitHub
- Today
- Total
이동식 저장소
1615. 교차개수세기 본문
뭔가 많이 본 듯한 문제이다. 어디서 봤나 했더니 2568번 전깃줄 문제와 매우 유사하다. 물론 풀이가 유사하다는 건 아니고 그림이 비슷하다는 소리. 이 문제에서는 전깃줄이 교차하는 횟수를 세어야 한다.
문제에 두 전깃줄이 교차하는 조건이 주어져 있는데, 계산의 편의를 위해 왼쪽에 있는 정점을 오름차순으로 살펴보면서, 각 정점의 전깃줄이 다른 전깃줄과 몇 번 교차하는지 계산해 보자.
왼쪽 정점 $i$와 오른쪽 정점 $j$에 연결된 전깃줄을 $(i, ~j)$이라고 하자. 전깃줄 $(i,~j)$에 대해 $a < i$이고 $b > j$인 전깃줄 $(a,~b)$의 개수를 세어야 한다. $a > i$인 경우를 세지 않는 이유는 정점을 오름차순으로 보고 있기 때문이다.
당연히 매번 모든 간선을 탐색하면 안 된다. 그러면 총 시간복잡도가 $O(M^{2})$인데 $M$이 최대 $N^{2}$이므로 $O(N^{4})$에 푸는 셈이다. 말이 안 된다.
그러면 어떻게 해야 하느냐.. 주어진 전깃줄을 표로 나타내 보자.
행과 열은 각각 왼쪽 정점과 오른쪽 정점을 나타낸다.
다시 한 번 식을 살펴보면, 전깃줄 $(i,~j)$에 대해 $a < i$이고 $b > j$인 전깃줄 $(a,~b)$의 개수를 세어야 한다. 예를 들어 전깃줄 $(3,~2)$에 대해 탐색해야 하는 영역은 다음과 같다.
전깃줄 $(5, ~3)$의 영역은 다음과 같다.
일반화하면 전깃줄 $(i,~j)$에 대해 $[1,~j+1] \times [i-1,~n]$ 영역의 합을 구하면 된다. 이 값은 2차원 부분합으로 쉽게 계산할 수 있다. 부분합을 계산하는 데 $O(N^{2})$, 각 간선에 대해 부분합을 얻는 데 $O(M)$ 시간이 걸리므로 총 $O(N^{2})$ 시간에 문제를 풀 수 있다.
참고로 long long 써야 한다. 흑흑
'Problem Solving > BOJ' 카테고리의 다른 글
12996. Acka (0) | 2023.04.14 |
---|---|
1572. 중앙값 (0) | 2023.04.10 |
14719. 빗물 (0) | 2023.03.25 |
20925. 메이플스토리 (0) | 2023.03.25 |
13418. 학교 탐방하기 (0) | 2022.12.01 |