Link

https://www.acmicpc.net/problem/16566

Detail

결국 입력으로 가진 카드를 받고, 주어지는 Input마다 upper_bound 값을 찾아 반환하면 된다.

Union_Find 방식을 사용해서 Table[i] = i 보다 큰 최소의 카드를 저장하여 해결했다. 카드를 사용했을 경우 Table[card]의 값을 1늘려서 체인을 걸면 해결할 수 있다.

# Code
#include<bits/stdc++.h>
 
#define MAX 4000000
#define FAST_IO ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
 
using namespace std;
 
// Table[i] = 가진 카드 중 i보다 크거나 같은 최소의 카드
vector<int> Table;
int N, M, K;
 
int get_min_big(int number) {
	if(Table[number] == number) {
		return number;
	}
 
	return Table[number] = get_min_big(Table[number]);
}
 
void set_table() {
    vector<int> cards(M);
 
    for(int i = 0; i < M; i++) {
        cin >> cards[i];
    }
 
    sort(cards.begin(), cards.end());
 
    int cur_card = 0;
    for(int i = 1; i <= MAX; i++) {
        if(i > cards[cur_card]) {
            if(cur_card == M - 1) {
                break;
            }
            cur_card++;
        }
 
        Table[i] = cards[cur_card];
    }
}
 
int main() {
    FAST_IO;
 
    cin >> N >> M >> K;
    Table.resize(MAX + 1);
 
    set_table();
 
    int target;
    for(int i = 0; i < K; i++) {
        cin >> target;
 
        if(Table[target] == target) { 
        // 예외 케이스 : Table은 "이상"을 기준으로 하나, 
        // 문제에서는 초과하는 숫자를 가진 값을 정답으로 반환해줘야 함
        // 따라서 이 경우 문제가 되는 target은 1을 추가해서 계산
            target++;
        }
        int card = get_min_big(target);
        Table[card] = get_min_big(card + 1);
 
 
        cout << card << '\n';
    }
 
}