๐Ÿ•๏ธ ICPC Sinchon/Segment Tree

[BOJ][C++] ๋ฐฑ์ค€ 2042๋ฒˆ: ๊ตฌ๊ฐ„ ํ•ฉ ๊ตฌํ•˜๊ธฐ (Gold I)

์„ ๋‹ฌ 2025. 2. 4. 03:38
๋ฐ˜์‘ํ˜•

๋ฌธ์ œ

์–ด๋–ค N๊ฐœ์˜ ์ˆ˜๊ฐ€ ์ฃผ์–ด์ ธ ์žˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ค‘๊ฐ„์— ์ˆ˜์˜ ๋ณ€๊ฒฝ์ด ๋นˆ๋ฒˆํžˆ ์ผ์–ด๋‚˜๊ณ  ๊ทธ ์ค‘๊ฐ„์— ์–ด๋–ค ๋ถ€๋ถ„์˜ ํ•ฉ์„ ๊ตฌํ•˜๋ ค ํ•œ๋‹ค. ๋งŒ์•ฝ์— 1,2,3,4,5 ๋ผ๋Š” ์ˆ˜๊ฐ€ ์žˆ๊ณ , 3๋ฒˆ์งธ ์ˆ˜๋ฅผ 6์œผ๋กœ ๋ฐ”๊พธ๊ณ  2๋ฒˆ์งธ๋ถ€ํ„ฐ 5๋ฒˆ์งธ๊นŒ์ง€ ํ•ฉ์„ ๊ตฌํ•˜๋ผ๊ณ  ํ•œ๋‹ค๋ฉด 17์„ ์ถœ๋ ฅํ•˜๋ฉด ๋˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ƒํƒœ์—์„œ ๋‹ค์„ฏ ๋ฒˆ์งธ ์ˆ˜๋ฅผ 2๋กœ ๋ฐ”๊พธ๊ณ  3๋ฒˆ์งธ๋ถ€ํ„ฐ 5๋ฒˆ์งธ๊นŒ์ง€ ํ•ฉ์„ ๊ตฌํ•˜๋ผ๊ณ  ํ•œ๋‹ค๋ฉด 12๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค.

์ž…๋ ฅ

์ฒซ์งธ ์ค„์— ์ˆ˜์˜ ๊ฐœ์ˆ˜ N(1 ≤ N ≤ 1,000,000)๊ณผ M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. M์€ ์ˆ˜์˜ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๋Š” ํšŸ์ˆ˜์ด๊ณ , K๋Š” ๊ตฌ๊ฐ„์˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š” ํšŸ์ˆ˜์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‘˜์งธ ์ค„๋ถ€ํ„ฐ N+1๋ฒˆ์งธ ์ค„๊นŒ์ง€ N๊ฐœ์˜ ์ˆ˜๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ๊ทธ๋ฆฌ๊ณ  N+2๋ฒˆ์งธ ์ค„๋ถ€ํ„ฐ N+M+K+1๋ฒˆ์งธ ์ค„๊นŒ์ง€ ์„ธ ๊ฐœ์˜ ์ •์ˆ˜ a, b, c๊ฐ€ ์ฃผ์–ด์ง€๋Š”๋ฐ, a๊ฐ€ 1์ธ ๊ฒฝ์šฐ b(1 ≤ b ≤ N)๋ฒˆ์งธ ์ˆ˜๋ฅผ c๋กœ ๋ฐ”๊พธ๊ณ  a๊ฐ€ 2์ธ ๊ฒฝ์šฐ์—๋Š” b(1 ≤ b ≤ N)๋ฒˆ์งธ ์ˆ˜๋ถ€ํ„ฐ c(b ≤ c ≤ N)๋ฒˆ์งธ ์ˆ˜๊นŒ์ง€์˜ ํ•ฉ์„ ๊ตฌํ•˜์—ฌ ์ถœ๋ ฅํ•˜๋ฉด ๋œ๋‹ค.
์ž…๋ ฅ์œผ๋กœ ์ฃผ์–ด์ง€๋Š” ๋ชจ๋“  ์ˆ˜๋Š” -263๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™๊ณ , 263-1๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์ •์ˆ˜์ด๋‹ค.

์ถœ๋ ฅ

์ฒซ์งธ ์ค„๋ถ€ํ„ฐ K์ค„์— ๊ฑธ์ณ ๊ตฌํ•œ ๊ตฌ๊ฐ„์˜ ํ•ฉ์„ ์ถœ๋ ฅํ•œ๋‹ค. ๋‹จ, ์ •๋‹ต์€ -263๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™๊ณ , 263-1๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์ •์ˆ˜์ด๋‹ค.

 

ํ’€์ด

์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ ์ฒซ ๋ฌธ์ œ..!

์ข€ ๋” ํŽธํ•˜๊ฒŒ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ์žฌ๊ท€ ์—†์ด ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ํ•จ์ˆ˜๋“ค์„ ๊ตฌํ˜„ํ–ˆ๋‹ค.

updateSegment : ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค (์ดˆ๊ธฐ ๋ฐฐ์—ด ์„ค์ •, a=1 -> ๊ฐ’ ๋ณ€๊ฒฝ)

getSum : ๋ถ€๋ถ„ํ•ฉ์„ ๊ตฌํ•œ๋‹ค (a=2 -> b๋ถ€ํ„ฐ c๊นŒ์ง€ ํ•ฉ ๊ตฌํ•˜๊ธฐ)

 

// ํ’€์ด : https://whkakrkr.tistory.com

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

using namespace std;

typedef long long ll;

ll n,m,k;
vector<ll>segment;

// b๋ฒˆ์งธ ์ˆ˜๋ฅผ c๋กœ ๋ฐ”๊พผ๋‹ค
void updateSegment(ll b, ll c) {
    ll idx = b + n;
    
    segment[idx] = c;
    while(idx!=1) {
        idx /= 2;
        segment[idx] = segment[idx*2] + segment[idx*2 + 1];
    }
}

// b๋ถ€ํ„ฐ c๊นŒ์ง€์˜ ๊ตฌ๊ฐ„ํ•ฉ
ll getSum(ll b, ll c) {
    ll left = b + n;
    ll right = c + n;
    
    ll sum = 0;
    while(left <= right) {
        if(left%2 == 1) {
            sum += segment[left];
            left++;
        }
        left = left/2;

        if(right%2 == 0) {
            sum += segment[right];
            right--;
        }
        right = right/2;
    }
    
    return sum;
}

int main() {
    ios_base::sync_with_stdio(false);
	cout.tie(NULL);
	cin.tie(NULL);
	
	ll a,b,c;
	cin >> n >> m >> k;
	
	// ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ ์ •์˜
	int origin = n;
	n = pow(2, floor(log2(4*n))-1);
	segment.assign(n*2, 0);
	for(ll i=0; i<origin; i++) {
	    cin >> c;
	    updateSegment(i, c);
	}
	
	for(ll i=0; i<m+k; i++) {
	    cin >> a >> b >> c;
	    
	    if(a==1) { // update tree
	        updateSegment(b-1, c);
	    } else if(a==2) { // get sum
	        cout << getSum(b-1, c-1) << "\n";
	    }
	}
	
    return 0;
}
๋ฐ˜์‘ํ˜•