※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 24941번 문제인 줄넘기이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/24941
24941번: 줄넘기
$Q$개의 질문에 대해, 줄넘기에 참여할 수 있는 학생 수의 최댓값을 한 줄에 하나씩 출력합니다. 만약 줄넘기를 할 수 없다면 0을 출력합니다.
www.acmicpc.net
어떤 학생이 줄넘기 줄을 왼쪽에서 잡고 있는다면 이 때 오른쪽에서 줄을 잡고 있을 학생의 위치는 고정되어있다는 점에 주목하자. 즉, 각 학생에 대하여 그 학생이 왼쪽에서 줄을 잡고 줄넘기를 한다면 그 때의 줄넘기에 참여하는 학생의 수는 항상 고정되어있다는 점에 주목하자.
따라서, Q개의 질문에서 주어지는 각 구간을 [L, R]로 표현할 때, 질문들을 R 오름차순으로 정렬해두고 스위핑해나가며 [1, R] 구간 내에서 새로 가능해진 줄넘기의 구간을 업데이트해나가는, 각 학생이 왼쪽에서 줄을 잡고 줄넘기를 할 때의 참여 학생수를 원소로 갖는 RMQ 세그먼트트리로 문제를 해결할 수 있다.
가능한 줄넘기의 구간들은 map을 이용하여 간단히 찾을 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <queue>
#include <map>
using namespace std;
int arr[500001];
int ans[500001];
int seg[1048577];
int upd(int L, int R, int qI, int qVal, int sI) {
if (R < qI || qI < L) return seg[sI];
if (L == R) return seg[sI] = qVal;
return seg[sI] = max(upd(L, (L + R) / 2, qI, qVal, sI * 2), upd((L + R) / 2 + 1, R, qI, qVal, sI * 2 + 1));
}
int qry(int L, int R, int qL, int qR, int sI) {
if (R < qL || qR < L) return 0;
if (qL <= L && R <= qR) return seg[sI];
return max(qry(L, (L + R) / 2, qL, qR, sI * 2), qry((L + R) / 2 + 1, R, qL, qR, sI * 2 + 1));
}
map<int, int> mp;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int,int>>> upd_PQ; // {오른쪽끝,왼쪽끝}
priority_queue<pair<pair<int, int>, int>, vector<pair<pair<int, int>, int>>, greater<pair<pair<int, int>, int>>> qry_PQ; // {{오른쪽끝,왼쪽끝},쿼리번호}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int N; cin >> N;
for (int i = 1; i <= N; i++) {
int x; cin >> x;
if (mp.find(x) == mp.end()) mp.insert({ x,i });
else {
upd_PQ.push(make_pair(i, mp[x]));
mp[x] = i;
}
}
int Q; cin >> Q;
for (int i = 0; i < Q; i++) {
int L, R; cin >> L >> R;
qry_PQ.push(make_pair(make_pair(R, L), i));
}
while (!qry_PQ.empty()) {
int id_qry = qry_PQ.top().second;
int L = qry_PQ.top().first.second, R = qry_PQ.top().first.first;
while (!upd_PQ.empty()) {
if (upd_PQ.top().first > R) break;
upd(1, N, upd_PQ.top().second, (upd_PQ.top().first - upd_PQ.top().second + 1), 1);
upd_PQ.pop();
}
ans[id_qry] = qry(1, N, L, R, 1);
qry_PQ.pop();
}
for (int i = 0; i < Q; i++) cout << ans[i] << '\n';
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 24426 // C++] 알고리즘 수업 - 행렬 경로 문제 3 (0) | 2022.04.10 |
---|---|
[BOJ 24429 // C++] 알고리즘 수업 - 행렬 경로 문제 6 (0) | 2022.04.10 |
[BOJ 24940 // C++] Split the GSHS (0) | 2022.04.08 |
[BOJ 24939 // C++] Boardle (0) | 2022.04.07 |
[BOJ 24938 // C++] 키트 분배하기 (0) | 2022.04.06 |