일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 호반우 상인
- 줄어드는수
- 코딩
- 최소 #공배수 #최대 #공약수 #유클리드 #호제법 #lcm #gcd #c++ #boj #3343 #백준 #장미
- 3D #Reconstruction #computer #vision #volume #metric #tsdf #kinect #fusion
- c++ #boj #
- 진법변환 #2to10 #10to2 #이진법 #십진법 #변환 #bitset #c++
- 쌤쌤쌤
- boj #백준
- BOJ
- 1174
- N번째큰수
- hcpc
- 투포인터 #백준 #boj #20922 #22862
- graph #최단경로
- LIS #가장긴증가하는부분수열 #
- 백준
- 사이클 없는 그래프
- 레드아보
- graph
- 22869
- 이분탐색 #dp #11053
- C++
- c++ #입출력 #속도 #ios #sync_with_stdio #cin #cout #tie
- 백준 #다익스트라 #dijkstra #9370 #c++
- 16202
- 3343
- backtracking #codetree #디버깅 #삼성코테
- 30870
- 20117
- Today
- Total
hyunjin
imos 알고리즘 - 누적합 문제 효율적으로 푸는 방법 본문
imos - 예제 문제 백준 20440 , 백준 3020, 백준 5541, 백준 16436, 카카오 파괴되지 않은 건물
imos (Indexed Modification of Sums)법
- 특정 구간을 빠르게 업데이트하고, 이를 통해 누적합을 구할 때 유용한 알고리즘
- 핵심은 업데이트 구간을 배열에 기록 후, 누적 합을 통해 최종 값을 계산
- 이외에서 육각형 좌표계 등 다양한 특수 좌표계에서 써먹을 수 있다.
- 수직선 위에 선을 여러 개 그어서, 가장 선이 많이 겹치는 부분 찾는 것
정해진 구간 내에서 시작과 끝이 포함된 부분 집합에 대한 명령이 여러 개 들어올 때, 반복적으로 연산하게 되면 연산 시간이 매우 커질 수 있다. O(QN)
상황 예시를 들어보면,
아래는 0 ~ 16 시 까지 한 장소에 대해 N명의 사람이 입장과 퇴장을 반복할 때, 각 시간에 대해 장소에 존재했던 사람이 몇명인지 구하는 상황. → imos 사용하지 않고 각 입장 퇴장 시간에 대해 반복문으로 연산하면 터진다.
구현
"입장과 퇴장만 기록한다"
각 명열에 대해 시작점과 끝점만 설정해 준 뒤, 마지막에 한 번의 반복을 통해 값을 계산. T(Q + N)
1차원 배열에서 구현
백준 3020,
- 각 시간에 대한 1차원 배열 생성하고 값을 0으로 초기화
- 각 입장, 퇴장에 대해 +1 , -1
만약 A(1시 ~ 4시), B(2시 ~ 8시), C(3시 ~ 12시), D(4시 ~ 8시) 동안 장소에 있었다면 배열의 값은
[0,1,1,1,0,0,0,0,-2,0,0,-1] 이 된다.
이 배열에 대해 for 돌리며 누적한다.
[0,1,2,3,3,3,3,3,1,1,1,0] 이 된다.
int imos[] = {0,1,1,1,0,0,0,0,-2,0,0,-1};
int sum = 0;
for (int& e : imos) {
sum += e;
e = sum;
}
2차원 배열에서의 구현
2차원 배열의 경우 격자 보드에 사각형 그리기
imos법은 특성상 고차원으로 확장이 용이하다.
$𝐻×𝑊 $ H×W 크기의 격자 보드가 있다. 각 칸의 초깃값은 모두 0이다.
다음과 같은 쿼리 $𝑄Q$개 들어온다.
$x1 y1 x2 y2 $ :
$𝑦1≤ℎ≤𝑦2y1≤h≤y2$ , $𝑥1≤𝑤≤𝑥2x1≤w≤x2$ 에 해당하는 모든 칸
(ℎ, 𝑤)(h, w) 의 값에 1을 더한다.
쿼리를 모두 처리한 뒤의 최종 보드의 상태를 출력하라.
나이브하게 푼다면 매 쿼리마다 해당 사각형 영역에 1씩 다 더한다. → O(QHW)
2차원 imos 배열의 경우 각 꼭지점에 대해
1. 사각형이 시작하는 부분 (왼쪽 위 점) : +1
2. 시작 부분에서 가로, 세로로 나아갔을 때 범위가 끝나는 부분 (빨간색 표시 지점) : -1
3. 사각형이 끝난 부분 (구간 밖 오른쪽 아래 점) -1 해준 걸 상쇄하기 위해 다시 : +1
특수 좌표계 imos
삼각형 형태인 경우 아래와 같이 진행
참고
https://driip.me/65d9b58c-bf02-44bf-8fba-54d394ed21e0
https://velog.io/@nkrang/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-imos-%EB%B2%95
'개인 공부 > 알고리즘' 카테고리의 다른 글
[C++] DFS 깊이 우선 탐색 알고리즘 (0) | 2021.02.18 |
---|---|
[C++] BFS 너비 우선 탐색 알고리즘 (0) | 2021.02.18 |
유클리드 호제법 알고리즘, 최대공약수, 최소공배수 (0) | 2021.02.16 |
insertion sort(삽입 정렬) 알고리즘 (0) | 2021.02.09 |
Dynamic Programming이란? (0) | 2021.02.03 |