티스토리 뷰
3006번: 터보소트
첫째 줄에 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이며, 배열의 크기이다. 둘째 줄부터 N개의 줄에는 1보다 크거나 같고, N보다 작거나 같은 수가 중복 없이 주어진다
www.acmicpc.net
풀이
각 숫자가 어느 자리에 있는지 먼저 기록한다. 숫자 i를 정렬할 때 맨 앞이나 맨 뒤로 보내 정렬하므로 숫자 i가 있는 위치와 가야되는 위치 사이에 있는 숫자의 개수를 파악하면 된다. 그리고 정렬된 숫자를 제외하고 같은 작업을 반복하면 된다. 1을 맨 앞, n을 맨 뒤로 추상화할 수 있다.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int tree[1 << 20];
int base, n;
vector<int> a;
int sum(int a, int b) {
a += base; b += base;
int res = 0;
while (a <= b) {
if (a % 2 == 1) res += tree[a++];
if (b % 2 == 0) res += tree[b--];
a /= 2; b /= 2;
}
return res;
}
void erase(int k) {
k += base;
tree[k] = 0;
for (k /= 2; k > 0; k /= 2) {
tree[k] = tree[2 * k] + tree[2 * k + 1];
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n;
for (base = 1; base < n + 1; base *= 2);
a = vector<int>(n + 1);
for (int i = 1; i <= n; i++) {
int t; cin >> t;
a[t] = i;
}
for (int i = base + 1; i < base + n + 1; i++) {
tree[i] = 1;
}
for (int i = base - 1; i > 0; i--) {
tree[i] = tree[2 * i] + tree[2 * i + 1];
}
for (int i = 1; i <= n; i++) {
if (i % 2 == 1) {
int t = (i + 1) / 2;
int pos = a[t];
erase(pos);
cout << sum(1, pos - 1) << '\n';
}
else {
int t = n - (i - 1) / 2;
int pos = a[t];
erase(pos);
cout << sum (pos + 1, n) << '\n';
}
}
return 0;
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 부트 캠프
- 백준 9345
- 인간 대포
- 제로베이스 백엔드 스쿨
- 백준 10775
- 백준 2336
- 백준 10473
- 백준 14868
- 백준 1106
- 터보소트
- boj 9345
- boj 14868
- boj 2336
- 백준 1280
- 백준 12713
- 사탕상자
- boj 12713
- boj 10775
- 백준 2243
- 백준 3006
- 디지털 비디오 디스크
- boj 1106
- boj 10473
- 백준 16562
- boj 2243
- boj 16562
- 제로베이스 스쿨
- boj 1280
- boj 3006
- Ugly Numbers
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함