※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 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(NlgN)이다.

 

아래는 제출한 소스코드이다.

#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

+ Recent posts