※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 30646번 문제인 최대 합 순서쌍의 개수이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/30646
30646번: 최대 합 순서쌍의 개수
크기가 N인 배열 a가 주어진다. 배열 a의 임의의 위치를 나타내는 두 수 i, j를 골랐을 때, 아래 두 조건을 만족하면 같은 수 순서쌍 (i, j)를 만들 수 있다. 1 ≤ i ≤ j ≤ N ai = aj 만들어진 같은 수 순
www.acmicpc.net
주어진 배열에 등장하는 수 \(x\)에 대하여 해당 수를 양 끝으로 갖는 "순서쌍의 최대 합"은 배열에 처음 등장한 \(x\)의 위치부터 마지막으로 등장한 \(x\)의 위치까지의 구간합과 같음을 관찰하자.
따라서 주어진 배열에 등장하는 각 원소에 대하여 처음 등장한 위치와 마지막으로 등장한 위치를 map 등을 이용해 관리하고, 구간합을 빠르게 구하기 위해 prefix sum을 이용하는 것으로 문제를 해결할 수 있다. 시간복잡도는 map을 사용하는 데에 따라 발생하는 \(O(N\lg N)\)이다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
int N;
ll arr[200001];
map<int, int> L, R;
ll ans, cnt;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N;
for (int i = 1; i <= N; i++) {
int x; cin >> x;
arr[i] = arr[i - 1] + x;
if (L.count(x)) {
L[x] = min(L[x], i), R[x] = max(R[x], i);
}
else {
L.insert(make_pair(x, i)), R.insert(make_pair(x, i));
}
}
for (auto& p : L) {
ll val = arr[R[p.first]] - arr[p.second - 1];
if (val > ans) ans = val, cnt = 1;
else if (val == ans) cnt++;
}
cout << ans << ' ' << cnt;
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 24504 // C++] blobcry (1) | 2024.02.29 |
---|---|
[BOJ 9344 // C++] 도로 (1) | 2024.02.28 |
[BOJ 30644 // C++] 띠 정렬하기 (0) | 2024.02.26 |
[BOJ 14446 // C++] Promotion Counting (1) | 2024.02.25 |
[BOJ 27532 // C++] 시계 맞추기 (0) | 2024.02.24 |