본문 바로가기
카테고리 없음

(java) BOJ 14427 수열과 쿼리 15

by 펀구구 2023. 7. 14.
 

14427번: 수열과 쿼리 15

길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. 1 i v : Ai를 v로 바꾼다. (1 ≤ i ≤ N, 1 ≤ v ≤ 109) 2 : 수열에서 크기가 가장 작은 값의 인덱스를 

www.acmicpc.net

문제 풀이

이 문제는 자료구조를 활용해서 문제를 푸는 것이 핵심이다. priority queue를 사용해서 O(logN)안에 수열에서 가장 큰 수를 뽑아낼 수 있다. 하지만 pq 내의 값을 변경해야 하는 경우가 생긴다. 이 때 pq내의 값을 직접 바꾸는 것이 아니라 값에 대한 version을 도입해서 최신 version의 값이 아니라면 pq에서 나온 값을 무시하는 식으로 코드를 짰다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;

public class Main {

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		int N = Integer.parseInt(in.readLine());
		String[] str = in.readLine().split(" ");
		
        //해당 인덱스의 버전을 기록하는 배열
		int[] change_count = new int[N + 1];

		PriorityQueue<int[]> pq = new PriorityQueue<>(new Comparator<int[]>() {
			@Override
			public int compare(int[] o1, int[] o2) {
				if(o1[0] == o2[0]) return o1[1] - o2[1];
				else return o1[0] - o2[0];
			}
		});

		for(int i = 0; i < N; i++) {
			int num =Integer.parseInt(str[i]); 
			pq.offer(new int[] {num, i + 1, 0});
		}
		
		
		int M = Integer.parseInt(in.readLine());
		for(int i = 0; i < M; i++) {
			String cmd = in.readLine();
			if(cmd.equals("2")) { // 2명령일 때
				int now[];
				while(true) {
					now = pq.peek();
                    //최신 버전이면
					if(change_count[now[1]] == now[2]) {
						sb.append(now[1] + "\n");
						break;
					}else { //최신 버전이 아니라면
						pq.poll();
					}
				}
				
			}
			else { // 1명령일 때
				String[] cmd1 = cmd.split(" ");
				
				int num = Integer.parseInt(cmd1[2]);
				int index = Integer.parseInt(cmd1[1]);
				change_count[index]++;
				pq.offer(new int[] {num, index, change_count[index]});
			}
		}
		System.out.print(sb);
	}
}