-
영화 수집 - 3653Algorithm/BOJ 2020. 3. 5. 03:5412345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667//3653 - 영화 수집#include <iostream>#include <vector>using namespace std;int N, M;int idx[100001];struct FenwickTree{vector<int> tree;FenwickTree(int n) : tree(n, 0) {}int sum(int pos){int ret = 0;while(pos > 0){ret += tree[pos];pos &= (pos-1);}return ret;}void add(int pos, int val){while(pos <= N+M){tree[pos] += val;pos += (pos & -pos);}}};void init(){cin >> N >> M;for(int i = 1; i<=N; ++i)idx[i] = M+i;}int main(){ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);int C; cin >> C;for(int tn = 0; tn<C; ++tn){init();FenwickTree fwt(N+M+1);for(int i = 1; i<=N; ++i)fwt.add(idx[i], 1);int u;int to = M;for(int i = 0; i<M; ++i){cin >> u;int from = idx[u];cout << fwt.sum(from-1) << " ";fwt.add(from, -1);idx[u] = to;fwt.add(to--, 1);}cout << "\n";}}
cs https://www.acmicpc.net/problem/3653
3653번: 영화 수집
문제 상근이는 영화 DVD 수집가이다. 상근이는 그의 DVD 콜렉션을 쌓아 보관한다. 보고 싶은 영화가 있을 때는, DVD의 위치를 찾은 다음 쌓아놓은 콜렉션이 무너지지 않게 조심스럽게 DVD를 뺀다. 영화를 다 본 이후에는 가장 위에 놓는다. 상근이는 DVD가 매우 많기 때문에, 영화의 위치를 찾는데 시간이 너무 오래 걸린다. 각 DVD의 위치는, 찾으려는 DVD의 위에 있는 영화의 개수만 알면 쉽게 구할 수 있다. 각 영화는 DVD 표지에 붙어있는 숫
www.acmicpc.net
영화 수집
일자로 쭉 서있는 원소들 중에서 하나를 선택해 그 앞에 있는 원소의 수를 출력하고, 해당 원소를 맨 앞으로 보내는 과정을 반복합니다.
원소의 수 만큼 선형 자료구조를 만들어 위 작업을 반복하면, 원소들의 위치를 조정하는 과정에서 시간초과가 발생합니다.
원소들의 위치를 조정하는 작업 없이 똑같은 효과를 내어야 하는데, 굳이 빈 자리를 매꾸지 않으면 됩니다.
이를위해 선형자료구조를 N+M크기로 잡아주고, 초기에 M+1 .... M+N 위치에 원소들을 자리시킨다음, 앞으로 이동해야 하는 원소만 순서대로 M, M-1, M-2... 위치로 이동시키고 부분합을 구하게 되면 원소들의 위치를 조정하는 과정 없이 똑같은 효과를 낼수 있습니다.
부분합을 구하는 방법은 펜윅트리를 사용하면 빠르게 구할 수 있기 때문에 시간초과 없이 문제를 해결할 수 있습니다.
(펜윅트리의 sum, add 는 lgn만큼의 시간복잡도를 가집니다. 따라서 총 nlgn만에 해결할 수 있습니다.)
'Algorithm > BOJ' 카테고리의 다른 글
전국시대 - 15809 (0) 2020.03.07 전구 - 2449 (0) 2020.03.05 구간 합 구하기 4 - 11659 (0) 2020.03.04 구간 합 구하기 5 - 11660 (0) 2020.03.04 임계경로 - 1948 (0) 2020.03.04