티스토리 뷰
#include <stdio.h>
#include <stdlib.h>
typedef struct A{int x,y; /*x (index) y (value)*/}A;
int tree[2000000] = {};
int compare(const void *a, const void *b) { //value 기준 오름차순 정렬
return (*(A*)a).y - (*(A*)b).y;
}
int update(int s, int e, int node, int index) {
if(s>index || e<index) return tree[node];
if(s==e) return tree[node] = 1;
int m = (s+e)/2;
return tree[node] = update(s,m,node*2,index) + update(m+1,e,node*2+1,index);
}
int find(int s, int e, int node, int l, int r) {
if(s>r || e<l) return 0;
if(l<=s & e<=r) return tree[node];
int m = (s+e)/2;
return find(s,m,node*2,l,r)+find(m+1,e,node*2+1,l,r);
}
int main(void) {
int n,m;
long long ans = 0;
scanf("%d",&n);
A arr[n];
for(int i=0; i<n; i++) {
scanf("%d",&m);
arr[i].x = i;
arr[i].y = m;
}
qsort(arr, n, sizeof(A), compare);
for(int i=n-1; i>=0; i--) {
ans += find(0,n-1,1,0,arr[i].x-1);
update(0,n-1,1,arr[i].x);
} printf("%lld",ans);
}
풀이 : 세그먼트 트리,정렬
0. 세그먼트 트리를 준비합니다. 특정 index의 값을 1씩 늘리는 update와 구간합을 가져오는 find을 준비합니다.
1. 입력을 언제 받았는가 (x) 입력값이 무엇인가(y)을 한묶음으로 저장합니다.
2. y를 기준으로 오름차순 정렬을 합니다 (위의 데이터를)
3. y값이 큰 데이터부터 순차적으로 (내림차순) 다룹니다.
3.1 특정 y값이 입력되기 전에 더 큰 숫자들의 개수를 구합니다. 그리고 이것을 ans에 누적합니다.
3.2 그다음, y값이 입력이 되었던 순서를(x값) index로 하여 세그먼트 트리에 update을 해줍니다 (관련된 노드의 값이 1씩 증가하게 됩니다)
핵심은 정렬을 한 후 큰 숫자(y값)부터 다루며, 이 숫자가 입력되기 전에(x값) 이보다 더 큰 수가 몇 개 있는지를 확인(find)하고 ( 큰 수의 개수가 swap을 해야할 횟수와 같습니다) 다음에 더 작은 수를 위해서 세그먼트 트리에 x번째에 큰 수 가 있다는 것을 update해줍니다. 이 과정을 반복하면 전체 swap 횟수를 구할 수 있습니다!!!!
https://www.acmicpc.net/problem/1517
'c언어 > BAEKJOON' 카테고리의 다른 글
c언어 12844번 XOR (백준) (0) | 2024.08.13 |
---|---|
c언어 9345번 디지털 비디오 디스크(DVDs) (백준) (0) | 2024.08.12 |
c언어 1168번 요세푸스 문제 2 (백준) (0) | 2024.08.08 |
c언어 11505번 구간 곱 구하기 (백준) (0) | 2024.08.06 |
c언어 12899번 데이터 구조 (백준) (0) | 2024.08.05 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 1835번
- 브루트포스
- 백준
- Krustal
- 누적합
- 1835
- C언어
- 덱
- DFS
- 플로이드
- Segment Tree
- find
- union
- 세그먼트 트리
- XOR
- PASCAL
- java
- 그래프
- 오프라인 쿼리
- 정렬
- C++
- 최소 스패닝 트리
- 누적 합
- 스택
- BFS
- Lazy Propagation
- 기하학
- DP
- 그리디
- 최대공약수
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함