/*
* Problem :: 1713 / 후보 추천하기
*
* Kind :: Simulation
*
* Insight
* - 다음과 같은 정보를 항상 알고 있어야 한다
* + 사진틀에 올라간 학생들의 번호
* + 사진틀에 올라간 학생들의 순서
* + 사진틀에 올라간 학생들의 추천받은 횟수
* # Frame 이라는 구조체를 정의하고 (vector<Frame>) F 를 선언해서
* 현재 사진틀에 올라간 학생들의 정보를 추적하자
*
* Point
* - 근데 위의 F 에서 번호가 10 인 학생을 어떻게 찾지?
* + for 문을 써서 찾을 수 있지만... 폼이 안난다
* 뭔가 <alogirhtm> 에서 find 를 잘 활용하면 될 것 같은데...
* # predicate 를 활용하자!
* + 현재까지 추천 받은 횟수가 가장 적고 가장 오래된 학생도
* <algorithm> 에서 min_element 를 잘 활용하면 될 것 같은데...
* # < 연산자 오버로딩을 활용하자!
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define endl '\n'
// Set up : Global Variables
struct Frame { int no, ord, likes; };
// Set up : Functions Declaration
bool operator < (Frame u, Frame v);
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N; cin >> N;
int M; cin >> M;
int R[M];
for (int i=0; i<M; i++)
cin >> R[i];
// Process
vector<Frame> F; /* 현재 사진틀에 올라간 학생들의 정보 <= 정렬되어있지는 않음
* 사진틀은 학생의 번호, 게시된 순서, 추천받은 횟수를 정보로 가지고 있음 */
for (int i=0; i<M; i++) {
int no = R[i]; /* 현재 추천받은 학생의 번호 */
/* 추천받은 학생의 번호와 같은 번호를 가진 사진틀의 인덱스(이터레이터)를 반환 */
auto p = find_if(F.begin(), F.end(), [no](Frame f) {
return f.no == no;
});
if (p != F.end()) { /* 추천받은 학생과 같은 번호를 가진 사진틀이 있다면 */
p->likes++; /* 그 학생의 추천받은 횟수 증가 */
} else { /* 추천받은 학생과 같은 번호를 가진 사진틀이 없다면 */
if (F.size() == N) { /* 현재 비어있는 사진틀이 없다면 */
/* 현재까지 추천받은 횟수가 가장 적고 가장 오래된 사진틀을 제거 */
F.erase(min_element(F.begin(), F.end()));
}
/* 새로운 사진틀 추가 */
F.push_back({no, i, 1});
}
}
/* 현재 사진틀에 있는 학생들의 번호가 오름차순이 되도록 정렬 */
sort(F.begin(), F.end(),
[](Frame u, Frame v) {
return u.no < v.no;
});
// Control : Output
for (Frame f : F) {
cout << f.no << ' ';
}
}
// Helper Functions
bool operator < (Frame u, Frame v)
/* Fraem 구조체 비교를 위한 연산자(<) 오버로딩 */
{
return make_pair(u.likes, u.ord) < make_pair(v.likes, v.ord);
}