Coding Is My Life

코딩은 인생

그래프 이론/세그먼트 트리

[백준/C++][구간 곱 구하기(11505번)-세그먼트 트리]

산기대 컴공 2020. 12. 30. 23:19
728x90

문제

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

 

11505번: 구간 곱 구하기

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이고, K는 구간의 곱을 구하는 횟수이다. 그리고 둘째 줄부터 N+1번째 줄

www.acmicpc.net

문제 풀이

이 문제는 세그먼트 트리를 이용해서 푸는 문제이다. 기본적으로 세그먼트 트리의 지식이 있어야 풀 수 있다.

세그먼트 트리에서 구간 합을 구하는 방법과 비슷하게 풀었다.

1. 초기화를 해줄 때 자식 노드들의 곱으로 노드를 초기화했다.

2. 업데이트를 해줄 때는 구간에 있는 노드들을 전부 바꿨다. (리프 노드도 바꾸어줌)-> 리프 노드부터 자식 노드들의 곱으로 바꿨다는 의미.

3. 구간 곱을 구할 때에는 구간이 아니라면 1을 반환(0을 반환하면 곱이므로 구간 곱이 0이 됨) 구간에 들어오면 해당 노드 반환, 겹치면 두 자식의 곱을 반환.

 

코드

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <vector>
#include <cmath>
#include <cstdio>
#define MOD 1000000007
using namespace std;
vector<int> v;
vector<long long> tree;
long long init(int node,int start,int end){
    if(start == end){
        return tree[node] = v[start];
    }
    else{
    return tree[node] = init(node*2,start,(start+end)/2)*init(node*2+1,(start+end)/2+1,end)%1000000007;
    }
}
long long update(int node,int start,int end,int idx,int num){
    if(idx>end || idx<start){return tree[node];}
    if(start == end){return tree[node] = num;}
    return tree[node] = update(node*2,start,(start+end)/2,idx,num)*update(node*2+1,(start+end)/2+1,end,idx,num)%1000000007;
}
long long sum(int node,int start,int end,int left,int right){
    if(left>end || right<start){return 1;}
    if(left<=start && right>=end){
        return tree[node];
    }
    else{
    return sum(node*2,start,(start+end)/2,left,right)*sum(node*2+1,(start+end)/2+1,end,left,right)%1000000007;
    }
}
int main(void){
    int N,M,K;
    scanf("%d%d%d",&N,&M,&K);
    v.resize(N);
    int h = (int)ceil(log2(N));
    int vector_size = (1<<(h+1));
    tree.resize(vector_size);
    for(int i = 0;i<N;i++){
        scanf("%d",&v[i]);
    }
    init(1,0,N-1);
    for(int i =0;i<M+K;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        if(a == 1){
            update(1,0,N-1,b-1,c);
        }
        else if(a == 2){
            cout << sum(1,0,N-1,b-1,c-1)<<"\n";
        }
    }
}
cs
728x90