티스토리 뷰

https://www.acmicpc.net/problem/2015

 

2015번: 수들의 합 4

첫째 줄에 정수 N과 K가 주어진다. (1 ≤ N ≤ 200,000, |K| ≤ 2,000,000,000) N과 K 사이에는 빈칸이 하나 있다. 둘째 줄에는 배열 A를 이루는 N개의 정수가 빈 칸을 사이에 두고 A[1], A[2], ..., A[N]의 순서로

www.acmicpc.net

 

 

map을 참신하게 활용하는 문제였습니다. 누적합은 $O(N)$에 구할 수 있습니다. 모든 부분합을 구하려고 하면 $O(N^{2})$으로 당연히 시간초과입니다.

 

 

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int N, K, arr[200001], curSum;
ll ans;
map<int, int> m;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    m[0]++;
    
    cin >> N >> K;

    for(int i=1; i<=N; i++) cin >> arr[i];

    for(int i=1; i<=N; i++){
        curSum += arr[i];
        ans += (ll)m[curSum-K];
        m[curSum]++;
    }

    cout << ans;

}

 

 

정답 코드를 보면, 매번 $i$번째 원소까지의 누적합을 구하면서 key가 누적합인 map을 증가시키고 있습니다.

 

map에 저장된 각 누적합의 개수는 $1 \sim i$번째 원소까지의 배열중 부분합이 $K$인 것들의 개수를 구할때 요긴하게 사용됩니다. $1 \sim i$번째 원소의 누적합이 curSum일 때, 앞선 누적합 중 그 값이 curSum-K인 것들의 개수를 보면됩니다.

$(curSum-K)+curSum=K$이기 때문입니다.

 

 

 

 

'알고리즘 문제풀이' 카테고리의 다른 글

BOJ 30960 조별 과제  (0) 2024.01.31
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31