[Baekjoon, 2143] 두 배열의 합
두 배열에 대한 모든 부분합을 미리 구한 다음, 한 배열을 정렬하고 이분탐색을 이용하여 답의 갯수를 찾으면 되는 문제이다.
나는 오랜만에 접한 lower_bound(), upper_bound() 함수가 정확히 어떤값을 반환하는지 헷갈렸다. 그래서 
정리하고자 이 글을 쓰게되었다.
lower_bound(): 찾으려는 값중 제일 첫 인덱스의 이터레이터를 반환한다. 없다면 찾으려는 값보다 큰 값중 가장 작은 값의 이터레이터를 반환한다.upper_bound(): 찾으려는 값보다 큰 값중 가장 작은 값의 이터레이터를 반환한다.
위의 함수를 이용하여 미리 구한 부분합에서 T = subsum1[i] + subsum2[j]를 만족하게 하는 구간의 크기를 모두 더하면 된다.
구현
#include <iostream>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cmath>
#include <climits>
#include <cctype>
using namespace std;
const int MAX = 1000 + 1;
int T, N, M;
vector<long long> calcSubsum(int arr[], int len) {
	vector<long long> ret;
	for (int i = 0; i < len; ++i) {
		long long sum = arr[i];
		ret.push_back(sum);
		for (int j = i + 1; j < len; ++j) {
			sum += arr[j];
			ret.push_back(sum);
		}
	}
	return ret;
}
int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);
	int A[MAX], B[MAX];
	cin >> T;
	cin >> N;
	for (int i = 0; i < N; ++i) {
		cin >> A[i];
	}
	cin >> M;
	for (int i = 0; i < M; ++i) {
		cin >> B[i];
	}
	vector<long long> subsum1 = calcSubsum(A, N);
	vector<long long> subsum2 = calcSubsum(B, M);
	sort(subsum2.begin(), subsum2.end());
	long long ret = 0;
	for (int i = 0; i < subsum1.size(); ++i) {
		int lo = lower_bound(subsum2.begin(), subsum2.end(), T - subsum1[i]) - subsum2.begin();
		int hi = upper_bound(subsum2.begin(), subsum2.end(), T - subsum1[i]) - subsum2.begin();
		ret += hi - lo;
	}
	cout << ret << endl;
	return 0;
}
      
댓글남기기