※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 6515번 문제인 Frequent values이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/6515
6515번: Frequent values
The input consists of several test cases. Each test case starts with a line containing two integers n and q (1 ≤ n, q ≤ 100000). The next line contains n integers a1 , ... , an (-100000 ≤ ai ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces
www.acmicpc.net
주어지는 수열이 단조증가한다는 조건을 확인하자.
수열이 단조증가하므로 이 수열의 모든 같은 수들은 서로 붙어있다. (사이에 다른 수를 두고 있을 수 없다.)
이를 이용하여, 1번 인덱스부터 i번 인덱스까지의 수열을 살폈을 때 i번 인덱스의 원소가 수열에서 몇번 등장했는지를 나타내는 배열을 만들어 쿼리가 들어올 때마다 이 배열의 구간에서의 최댓값을 구하는 것으로 문제를 대략 해결할 수 있다. 단, 배열의 범위의 앞부분은 연속된 수의 일부를 끊을 수 있으므로 이 부분에 대한 예외처리를 구현해주자.
이러한 작업을 할 수 있는 자료구조는 sparse table과 segment tree등이 있다.
지문 입력문단의 "The input consists of several test cases." 문장과 "The last test case is followed by a line containing a single 0." 가 무엇을 의미하는지 잘 생각하고, 글쓴이와 같은 허무한 이유로 문제를 틀리지 않기를 바란다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
using namespace std;
int arr[100001];
pair<int, int> seg[262145];
pair<int, int> init(int L, int R, int sI) {
if (L == R) return seg[sI] = make_pair(arr[L], L);
return seg[sI] = max(init(L, (L + R) / 2, sI * 2), init((L + R) / 2 + 1, R, sI * 2 + 1));
}
pair<int, int> rangemax(int L, int R, int qL, int qR, int sI) {
if (qR < L || R < qL) return make_pair(-1, -1);
if (qL <= L && R <= qR) return seg[sI];
return max(rangemax(L, (L + R) / 2, qL, qR, sI * 2), rangemax((L + R) / 2 + 1, R, qL, qR, sI * 2 + 1));
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int N, Q; cin >> N;
while (N) {
cin >> Q;
int old = -1000000007, cnt = -1;
for (int i = 1; i <= N; i++) {
int x; cin >> x;
if (x == old) cnt++;
else old = x, cnt = 1;
arr[i] = cnt;
}
init(1, N, 1);
while (Q--) {
int qL, qR; cin >> qL >> qR;
pair<int, int> qAns = rangemax(1, N, qL, qR, 1);
if (qAns.second - qL + 1 < qAns.first) {
if (qAns.second < qR) cout << max(qAns.second - qL + 1, rangemax(1, N, qAns.second + 1, qR, 1).first) << '\n';
else cout << qAns.second - qL + 1 << '\n';
}
else cout << qAns.first << '\n';
}
cin >> N;
}
}
'BOJ' 카테고리의 다른 글
[BOJ 14852 // C++] 타일 채우기 3 (0) | 2022.01.31 |
---|---|
[BOJ 23823 // C++] 초코칩 케이크 (0) | 2022.01.30 |
[BOJ 23256 // C++] 성인 게임 (0) | 2022.01.28 |
[BOJ 23974 // C++] 짝수 게임 (0) | 2022.01.27 |
[BOJ 23255 // C++] 구름다리 2 (0) | 2022.01.26 |