[C++] 백준(BOJ) - 3653 : 영화 수집

인프런에 있는 큰돌님의 강의 10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트를 듣고 정리한 필기입니다.

문제

BOJ - 3653 : 영화 수집(링크)

상근이는 영화 DVD 수집가이다. 상근이는 그의 DVD 콜렉션을 쌓아 보관한다.

보고 싶은 영화가 있을 때는, DVD의 위치를 찾은 다음 쌓아놓은 콜렉션이 무너지지 않게 조심스럽게 DVD를 뺀다. 영화를 다 본 이후에는 가장 위에 놓는다.

상근이는 DVD가 매우 많기 때문에, 영화의 위치를 찾는데 시간이 너무 오래 걸린다. 각 DVD의 위치는, 찾으려는 DVD의 위에 있는 영화의 개수만 알면 쉽게 구할 수 있다. 각 영화는 DVD 표지에 붙어있는 숫자로 쉽게 구별할 수 있다.

각 영화의 위치를 기록하는 프로그램을 작성하시오. 상근이가 영화를 한 편 볼 때마다 그 DVD의 위에 몇 개의 DVD가 있었는지를 구해야 한다.

입력

첫째 줄에 테스트 케이스의 개수가 주어진다. 테스트 케이스의 개수는 100개를 넘지 않는다.

각 테스트 케이스의 첫째 줄에는 상근이가 가지고 있는 영화의 수 n과 보려고 하는 영화의 수 m이 주어진다. (1 ≤ n, m ≤ 100,000) 둘째 줄에는 보려고 하는 영화의 번호가 순서대로 주어진다.

영화의 번호는 1부터 n까지 이며, 가장 처음에 영화가 쌓여진 순서는 1부터 증가하는 순서이다. 가장 위에 있는 영화의 번호는 1이다.

출력

각 테스트 케이스에 대해서 한 줄에 m개의 정수를 출력해야 한다. i번째 출력하는 수는 i번째로 영화를 볼 때 그 영화의 위에 있었던 DVD의 개수이다. 상근이는 매번 영화를 볼 때마다 본 영화 DVD를 가장 위에 놓는다.

알고리즘

  1. 팬윅트리
  2. 세그먼트 트리

풀이

  • 카운팅 트리
    • 노드가 1의 가중칭를 가진다
    • 좌표 이동을 하면서 update
  • 정답은 자기 자신을 제외한다

코드

// BOJ - 3653 : 영화 수집
#include <bits/stdc++.h>
using namespace std;

int t, n, m, tree[200004], tmp;
map<int, int> mp;

void update(int idx, int value)
{
	while (idx <= 200004)
	{
		tree[idx] += value;
		idx += (idx & -idx);
	}
}

int sum(int idx)
{
	int res = 0;
	while (idx > 0)
	{
		res += tree[idx];
		idx -= (idx & -idx);
	}
	return res;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	cin >> t;
	while (t--)
	{
		cin >> n >> m;
		memset(tree, 0, sizeof(tree));
		mp.clear();
		int update_idx = 100001;
		for (int i = 1; i <= n; i++)
		{
			update(i + update_idx, 1);
			mp[i] = i + update_idx;
		}
		for (int i = 0; i < m; i++)
		{
			cin >> tmp;
			int idx = mp[tmp];
			cout << sum(idx) - 1 << " ";
			update(idx, -1);
			update(--update_idx, 1);
			mp[tmp] = update_idx;
		}
		cout << '\n';
	}
	return 0;
}

평가

  • 팬윅트리
    • 이진트리 기반의 자료구조
    • ‘구간에 대한 연산’을 빠르게 하기 위한 자료구조
    • 세그먼트 트리에서 한 단계 더 응용된 자료구조로써 더 간단하고 더 적은 메모리로 주어진 연산을 처리할 수 있다
  • 루트노드부터 최소값 탐색이 O(logN)의 시간 복잡도를 가짐

© 2023 Jinsoo Lee. All rights reserved.

Powered by Hydejack v9.1.6