티스토리 뷰
풀이
각 숫자가 어느 자리에 있는지 먼저 기록한다. 숫자 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
- boj 12713
- boj 14868
- boj 2243
- 백준 10775
- 백준 2243
- 백준 2336
- 백준 14868
- 백준 1106
- 백준 9345
- boj 10473
- 디지털 비디오 디스크
- boj 10775
- 백준 1280
- 백준 3006
- boj 1280
- boj 3006
- 부트 캠프
- 제로베이스 백엔드 스쿨
- 인간 대포
- 백준 12713
- 사탕상자
- boj 9345
- boj 16562
- 백준 16562
- boj 2336
- 백준 10473
- 터보소트
- boj 1106
- 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 |
29 | 30 | 31 |
글 보관함