package boj;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class boj_18870 {
public static void main(String[] args) throws IOException {
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(System.out));
int count = Integer.parseInt(r.readLine());
List<Integer> read = Arrays.stream(r.readLine().split(" "))
.map(Integer::parseInt)
.collect(Collectors.toList());
if (read.size() == count) {
/**
* 이 코드 부분은 스트림의 각 요소(여기서는 좌표)에 대해 순서대로 연산을 수행합니다.
* forEachOrdered는 스트림의 정렬 순서를 보장하면서 각 요소에 대해 지정된 작업을 수행합니다.
* 여기서는 좌표를 rankMap에 저장하는데, 좌표가 키이고 값은 해당 좌표의 "순위"입니다.
*
* putIfAbsent: 이 메서드는 맵에 키가 존재하지 않는 경우에만 키-값 쌍을 저장합니다. 이미 키가 있다면 아무것도 하지 않습니다.
* rankMap.size(): 새 좌표를 맵에 추가할 때마다, 맵의 현재 크기가 그 좌표의 순위가 됩니다. 이는 이미 저장된 각 고유 좌표의 수를 나타냅니다.
*/
//좌표 순위매기기
Map<Integer, Integer> rankMap = new HashMap<>();
read.stream()
.sorted() // -10,-9,2,4,4
.distinct() // -10,-9,2,4
.forEachOrdered(
x -> rankMap.putIfAbsent(x, rankMap.size())); //좌표 순위 계산 = (-10,0),(-9,1),(2,2),(4,3)
/**
* map(rankMap::get): map 연산은 스트림의 각 요소를 다른 형태로 변환합니다.
* 여기서는 원래 좌표를 rankMap에서 찾아 해당 좌표의 순위로 변환합니다.
rankMap::get은 메서드 참조로, rankMap에서 각 좌표에 해당하는 순위를 검색합니다.
* collect(Collectors.toList()): 이는 변환된 스트림(순위로 변환된 좌표들)을 List로 수집합니다.
* 최종적으로 이 리스트는 원래 좌표의 순위를 나타내는 숫자로 이루어진 리스트가 됩니다.
*
*/
// 좌표 압축
List<Integer> result = read.stream()
.map(x -> rankMap.get(x))
.collect(Collectors.toList());
for (Integer e : result) {
w.write(e + " ");
}
w.flush();
}
}
}