문제: BOJ 3006 - 터보소트
터보소트는 매 단계마다 (남은 수 중) 최솟값/최댓값을 골라 인접 스왑으로 양 끝(또는 다음 위치)로 밀어넣는 과정이다.
각 단계에서 실제로 몇 번 스왑하는지는 “현재 배열에서 그 수의 앞/뒤에 남아있는 원소가 몇 개냐”로 바뀌므로, Fenwick Tree(BIT) 로 빠르게 계산할 수 있다.
문제 정보
문제 요약:
- 길이 \(N\)인 배열에 1..N이 중복 없이 한 번씩 등장한다.
- 1단계: 숫자 1을 찾아 인접 스왑으로 맨 앞으로 이동 (스왑 횟수 출력)
- 2단계: 숫자 N을 찾아 인접 스왑으로 맨 뒤로 이동 (스왑 횟수 출력)
- 3단계: 숫자 2를 찾아 인접 스왑으로 두 번째로 이동 …
- 이렇게 총 \(N\)단계 진행하며, 각 단계의 스왑 횟수를 출력한다.
제한 조건:
- 시간 제한: 1초
- 메모리 제한: 128MB
- \(1 \le N \le 100{,}000\)
입출력 예제
예제 입력 1:
| |
예제 출력 1:
| |
예제 입력 2:
| |
예제 출력 2:
| |
예제 입력 3:
| |
예제 출력 3:
| |
접근 방식
핵심 관찰
1..N의 값은 고정이고, 우리는 매 단계에서 특정 값 \(v\)의 현재 위치만 알면 된다.
- 홀수 단계(1,3,5,…): 남은 값 중 가장 작은 값 \(v\)를 왼쪽으로 밀어넣는다.
스왑 횟수 = \(v\)의 왼쪽에 남아있는 원소 개수 - 짝수 단계(2,4,6,…): 남은 값 중 가장 큰 값 \(v\)를 오른쪽으로 밀어넣는다.
스왑 횟수 = \(v\)의 오른쪽에 남아있는 원소 개수
즉, “아직 제거되지 않은 원소들만 1로 표시한 배열”을 두고 prefix/suffix 합을 구하면 된다.
Fenwick Tree(BIT) 모델링
- 입력에서 각 값 \(v\)의 초기 위치를
pos[v]로 저장 - BIT에는 “해당 인덱스가 아직 남아있으면 1, 제거되면 0”을 저장
- 단계마다:
- 홀수:
sum(pos[v]-1)출력 후add(pos[v], -1) - 짝수:
sum(N) - sum(pos[v])출력 후add(pos[v], -1)
- 홀수:
알고리즘 설계 (Mermaid Flowchart)
flowchart TD
A["입력 N, 수열 a[1..N]"] --> B["pos[value]에 초기 위치 저장"]
B --> C["BIT 초기화: 모든 인덱스에 1"]
C --> D["step = 1..N 반복"]
D --> E{"step이 홀수?"}
E -->|YES| F["v = (step+1)/2ans = sum(pos[v]-1)remove(pos[v])"]
E -->|NO| G["v = N - step/2 + 1ans = sum(N) - sum(pos[v])remove(pos[v])"]
F --> H["ans 출력"]
G --> H
H --> D
복잡도 분석
| 항목 | 복잡도 | 비고 |
|---|---|---|
| 시간 복잡도 | \(O(N \log N)\) | 단계당 BIT 쿼리/업데이트 2회 |
| 공간 복잡도 | \(O(N)\) | pos + BIT |
코너 케이스 및 실수 포인트
| 케이스 | 설명 | 처리 |
|---|---|---|
| N=1 | 한 줄 출력 | BIT 쿼리 결과가 0 |
| 입력은 N줄 | 값이 한 줄씩 들어옴 | for i=1..N에서 cin >> x |
| 1-indexed BIT | BIT는 1..N 인덱싱이 편함 | pos도 1..N 기반으로 저장 |
| long long 필요? | 출력은 최대 \(N\) 수준 | int도 가능하지만 안전하게 long long 사용 |
C++ 구현 코드
| |
![Featured image of post [Algorithm] C++ 백준 3006번: 터보소트](/post/algorithm/2025-12-19-boj-3006-turbosort-cpp-solution/wordcloud_hu_53c20b2375fe20d1.png)
![[Algorithm] C++ 백준 2586번: 소방차](/post/algorithm/2025-12-19-boj-2586-firetruck-cpp-solution/wordcloud_hu_c7df555f7b0ecd9e.png)
![[Algorithm] C++ 백준 2988번: 아보가드로](/post/algorithm/2025-12-19-boj-2988-avogadro-cpp-solution/wordcloud_hu_504f3f1bc728ef52.png)
![[Algorithm] C++ 백준 3006번: 터보소트](/post/algorithm/2025-12-19-boj-3006-turbosort-cpp-solution/wordcloud_hu_cd4b400156e60fdb.png)
![[Algorithm] C++ 백준 32115번: 돌 놓기 게임](/post/algorithm/2025-12-19-boj-32115-stone-placing-game-cpp-solution/wordcloud_hu_b5570483586eb270.png)
![[Algorithm] C++ 백준 32190번: Ian Sequences](/post/algorithm/2025-12-19-boj-32190-ian-sequences-cpp-solution/wordcloud_hu_266416599cd1461b.png)
![[Algorithm] C++ 백준 1777번: 순열복원](/post/algorithm/2025-12-19-boj-1777-permutation-recovery-cpp-solution/wordcloud_hu_e783e8b2198c2957.png)
![[Algorithm] C++ 백준 16745번: What Goes Up Must Come Down](/post/algorithm/2025-12-19-boj-16745-what-goes-up-must-come-down-cpp-solution/wordcloud_hu_8b312f25f2104ffa.png)
![[Algorithm] C++ 백준 33543번: 둘이 한 팀](/post/algorithm/2025-12-19-boj-33543-two-in-a-team-cpp-solution/wordcloud_hu_791f9bd4be457f3c.png)
![[Algorithm] C++ 백준 17965번: Absolute Game](/post/algorithm/2025-12-19-boj-17965-absolute-game-cpp-solution/wordcloud_hu_f6800a55fcd520be.png)