πŸ•οΈ PS (BOJ)/Segment Tree

[BOJ][C++] λ°±μ€€ 2357번: μ΅œμ†Ÿκ°’κ³Ό μ΅œλŒ“κ°’ (Gold I)

선달 2025. 2. 4. 23:31
λ°˜μ‘ν˜•

문제

N(1 ≤ N ≤ 100,000)개의 μ •μˆ˜λ“€μ΄ μžˆμ„ λ•Œ, a번째 μ •μˆ˜λΆ€ν„° b번째 μ •μˆ˜κΉŒμ§€ μ€‘μ—μ„œ 제일 μž‘μ€ μ •μˆ˜, λ˜λŠ” 제일 큰 μ •μˆ˜λ₯Ό μ°ΎλŠ” 것은 μ–΄λ €μš΄ 일이 μ•„λ‹ˆλ‹€. ν•˜μ§€λ§Œ 이와 같은 a, b의 쌍이 M(1 ≤ M ≤ 100,000)개 μ£Όμ–΄μ‘Œμ„ λ•ŒλŠ” μ–΄λ €μš΄ λ¬Έμ œκ°€ λœλ‹€. 이 문제λ₯Ό ν•΄κ²°ν•΄ λ³΄μž.
μ—¬κΈ°μ„œ aλ²ˆμ§ΈλΌλŠ” 것은 μž…λ ₯λ˜λŠ” μˆœμ„œλ‘œ aλ²ˆμ§ΈλΌλŠ” 이야기이닀. 예λ₯Ό λ“€μ–΄ a=1, b=3이라면 μž…λ ₯된 μˆœμ„œλŒ€λ‘œ 1번, 2번, 3번 μ •μˆ˜ μ€‘μ—μ„œ μ΅œμ†Œ, μ΅œλŒ“κ°’μ„ μ°Ύμ•„μ•Ό ν•œλ‹€. 각각의 μ •μˆ˜λ“€μ€ 1이상 1,000,000,000μ΄ν•˜μ˜ 값을 κ°–λŠ”λ‹€.

μž…λ ₯

첫째 쀄에 N, M이 μ£Όμ–΄μ§„λ‹€. λ‹€μŒ N개의 μ€„μ—λŠ” N개의 μ •μˆ˜κ°€ μ£Όμ–΄μ§„λ‹€. λ‹€μŒ M개의 μ€„μ—λŠ” a, b의 쌍이 μ£Όμ–΄μ§„λ‹€.

좜λ ₯

M개의 쀄에 μž…λ ₯받은 μˆœμ„œλŒ€λ‘œ 각 a, b에 λŒ€ν•œ 닡을 μ΅œμ†Ÿκ°’, μ΅œλŒ“κ°’ μˆœμ„œλ‘œ 좜λ ₯ν•œλ‹€.

 

풀이

μ„Έκ·Έλ¨ΌνŠΈ 트리~

// 풀이 : https://whkakrkr.tistory.com

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;

typedef long long ll;

ll INF = 1000000001;

int n,m, sz,x;
vector<ll> maxTree;
vector<ll> minTree;

void updateTree(int i, int val) {
    int idx = i + sz - 1;
    
    maxTree[idx] = val;
    minTree[idx] = val;
    
    while(idx>1) {
        idx /= 2;
        minTree[idx] = min(minTree[idx*2], minTree[idx*2+1]);
        maxTree[idx] = max(maxTree[idx*2], maxTree[idx*2+1]);
    }
}

int getMinMax(int a, int b, bool isMax) {
    ll ans = isMax ? 0 : INF;
    vector<ll>&tree = isMax ? maxTree : minTree;
    
    int left = a + sz - 1;
    int right = b + sz - 1;
    
    while(left <= right) {
        if(left%2 == 1) {
            ans = isMax ? max(ans, tree[left]) : min(ans, tree[left]);
            left++;
        }
        left /= 2;;
        
        if(right%2 == 0) {
            ans = isMax ? max(ans, tree[right]) : min(ans, tree[right]);
            right--;
        }
        right /= 2;
        
    }
    
    return ans;
}


int main() {
    ios_base::sync_with_stdio(false);
	cout.tie(NULL);
	cin.tie(NULL);
	
	cin >> n >> m;
	sz = pow(2, floor(log2(4*n)-1));
	maxTree.assign(2*sz, 0);
	minTree.assign(2*sz, INF);
	for(int i=1; i<=n; i++) {
	    cin >> x;
	    updateTree(i, x);
	}
	
	int a, b;
	while(m--) {
	    cin >> a >> b;
	    cout << getMinMax(a,b,false) << " " << getMinMax(a,b,true) << "\n";
	}
	
    return 0;
}

 

λ°˜μ‘ν˜•