Logo냥냠감자기술 블로그
Skip to Content
작성일: 2024-01-12

문제

백준 2268 - 수들의 합 

  • 난이도: 골드1
  • 알고리즘: 세그먼트 트리

코드

#include <iostream> #include <vector> #include <algorithm> using namespace std; long long init(int start, int end, int node, vector<long long>& inputs, vector<long long>& segTree) { if(start==end) { return segTree[node]=inputs[start]; } int mid=(start+end)/2; return segTree[node]=init(start, mid, node*2, inputs, segTree)+init(mid+1, end, node*2+1, inputs, segTree); } long long sumSeg(int start, int end, int node, int rangeLow, int rangeHigh, vector<long long>& segTree) { if(rangeHigh<start || rangeLow>end) return 0; if(start>=rangeLow && end<=rangeHigh) return segTree[node]; int mid=(start+end)/2; return sumSeg(start, mid, node*2, rangeLow, rangeHigh, segTree)+sumSeg(mid+1, end, node*2+1, rangeLow, rangeHigh, segTree); } long long change(int start, int end, int node, int targetIndex, long long changeTo, vector<long long>& segTree) { if(start>targetIndex || end<targetIndex) return segTree[node]; if(start==end) return segTree[node]=changeTo; int mid=(start+end)/2; return segTree[node]=change(start, mid, node*2, targetIndex, changeTo, segTree)+change(mid+1, end, node*2+1, targetIndex, changeTo, segTree); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int nodeNum, calNum; cin>>nodeNum>>calNum; vector<long long> inputs(nodeNum, 0); vector<long long> segTree(4000000, -1); init(0, nodeNum-1, 1, inputs, segTree); for(int i=0; i<calNum; i++) { int flag, num1, num2; cin>>flag>>num1>>num2; if(flag==0) { if(num1>num2) { swap(num1, num2); } cout<<sumSeg(0, nodeNum-1, 1, num1-1, num2-1, segTree)<<"\n"; } else { change(0, nodeNum-1, 1, num1-1, num2, segTree); } } }

회고

드디어 1트만에 풀었다…! 감격스럽다. 이런 대놓고 세그먼트 트리로 풀라는 식의 문제는 이제 잘 풀수 있을 거 같다. 문제는 역시 세그먼트 트리를 적용할 문제와 그렇지 않은 문제를 구분하는 것이다. 지금까지 백준에서 600문제 조금 안되는 문제를 풀어봤는데, 어떤 알고리즘을 적용하면 좋을지 판단하는 것은 여전히 어렵다. 한 2천문제 정도 풀면 되지 않을까 싶다.