구간합 구하기
☝🏻 prefixSum 구할때
// #include<bits/stdc++.h>
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
typedef long long ll;
int a[100004],b,c,psum[100004],n,m;
int main() {
cin >> n >> m;
for(int i=1;i<= n;i++) {
cin >> a[i];
}
for (int i=0; i<m; i++) {
cin >> b >> c;
int sum = 0;
for(int j =b;j <= c;j++) sum += a[j];
cout << sum << '\n';
}
return 0;
}
위와 같이 구간합을 구할 수 있다.
위의 코드 로직을 설명하면 다음과 같다.
- 배열을 하나 만든다.
- 그 배열에는 1~N까지의 수를 넣음
- 두번째 배열을 만든다.
- 그 배열에는 첫번째 배열의 요소를 더해가면서 구간합을 배열에 저장한다.
하지만 위의 코드의 가장 큰 문제는 시간복잡도가 크다는 것이다.
n과 m의 크기가 100000일 경우를 생각해보자.
그렇다면 시간복잡도는 100,000 * 100,000의 크기를 가진다.
즉, 위의 프로그램의 시간복잡도는 100억이다.
따라서 다른 방법을 사용해야한다.
그렇기에 필요한 것이 prefixSum이다.
먼저 코드를 보자.
// #include <bits/stdc++.h>
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
typedef long long ll;
int a[100004],b,c,psum[100004],n,m;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin.tie(NULL);
cin >> n >> m;
for(int i = 1;i <= n;i++) {
cin >> a[i];
psum[i] = psum[i-1] + a[i];
}
for (int i = 0; i < m; i ++) {
cin >> b >> c;
cout << psum[c] - psum[b-1] << "\n";
}
return 0;
}
위의 코드는 psum이라는 배열을 선언해두고, 구간합을 다음의 공식을 사용한다.
이를 이용하여 다음과 같이 표현할 수 있었다.
psum[i] = psum[i-1] + a[i];
이를 통해 기존 100억이라는 시간복잡도가
위의 코드에서는 100,000이라는 값을 가지게 된다.
Leave a comment