11505번

2023. 3. 2. 16:40·CS 이론/알고리즘
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

이 문제는 세그먼트 트리를 구현하면 된다.

트리를 구간 곱으로 초기화하고, 리프노드를 바꿔야 할 때는 노드 갱신 메서드를 사용해서 바꿔서 계산해준다.

구간 곱을 계산하는 메서드를 구현하는 과정에서 처음에 구하려는 구간 곱의 범위 밖에 있는 경우에 리턴 값을 0으로 해서 구간 곱이 모두 0이 되어서 안되었다. 그래서 이유가 뭔가 생각했는데, 그림으로 이해하면 쉬울 것이다.

 

 

예를 들어 아래의 그림에서 구하려는 구간이 3~5라고하면, 2X3인 6에서 필요한건 3만이기 때문에 2 대신 1을 반환해야한다.

그래서 아래의 조건을 사용한다. 범위 외의 있는 곳은 0이 아닌 1을 반환하도록 해야 구할 수 있다. 0을 사용하면 3~5를 구간곱을 구하는 과정에서 3에서 반환되는 값이 0이기 때문에 0으로 나온다.

if(left>end || right<start){
    return 1;
}

그리고 범위에 있는 값이면 그 구간 곱을 반환하는 로직은 아래와 같은 조건으로 처리한다.

if(left<=start && right>=end){
    return tree[idx];
}

이에 대해서 세그트리로 왼쪽, 오른쪽 자식으로 나누어 들어가면서 구간 곱을 계산한다.

int mid = (start+end)/2;
return interval_multiple(start,mid,idx*2,left,right)*interval_multiple(mid+1,end,idx*2+1,left,right)%mod;

 

정답 코드는 아래와 같다.

package backjoon.b11505;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class b11505 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());
        long[] arr = new long[N+1];
        for(int i=1; i<=N; i++){
            arr[i] = Integer.parseInt(br.readLine());
        }//1 2 3 4 5
        tree t = new tree(N, arr);
        t.init(1,N,1);//tree 초기화
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<M+K; i++){
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());//명령 코드
            int b = Integer.parseInt(st.nextToken());//1: 바꾸려는 위치, 2:구간곱 시작 지점
            long c = Integer.parseInt(st.nextToken());//1: 바꾸려는 값, 2:구간곱 끝 지점
            if(a==1){
                t.update(1,N,1,b,c);//구간 변화
                t.arr[b]=c;
            }else {
                sb.append(t.interval_multiple(1,N,1,b,c)).append("\n");
            }
        }
        System.out.println(sb);
    }
}
class tree{
    final static long mod = 1000000007;
    long[] arr;
    long[] tree;
    int N;

    public tree(int n, long[] arr) {
        N = n;
        tree = new long[n*4];
        this.arr = arr;
    }

    public long init(int start, int end, int idx){
        if(start==end){
            return tree[idx]=arr[start];
        }
        int mid = (start+end)/2;
        return tree[idx]=init(start,mid,idx*2)*init(mid+1,end,idx*2+1)%mod;
    }
    public long interval_multiple(int start, int end, int idx, int left, long right){
        if(left>end || right<start){
            return 1;
        }
        if(left<=start && right>=end){
            return tree[idx];
        }
        int mid = (start+end)/2;
        return interval_multiple(start,mid,idx*2,left,right)*interval_multiple(mid+1,end,idx*2+1,left,right)%mod;
    }
    public void update(int start, int end, int idx, int what, long value){
        if(what<start || what>end){
            return;
        }

        if(start==end){
            tree[idx]=value;
            return;
        }

        int mid = (start+end)/2;

        update(start,mid,idx*2,what,value);
        update(mid+1,end,idx*2+1,what,value);

        tree[idx] = tree[2 * idx] * tree[2 * idx + 1]%mod;
    }
}
728x90

'CS 이론 > 알고리즘' 카테고리의 다른 글

4195번(유니온 파인드)  (0) 2023.03.09
17352번 (유니온파인드)  (0) 2023.03.06
11404번(플로이드 워셜)  (0) 2023.03.01
1956번(플로이드 워셜)  (1) 2023.02.28
2042번  (0) 2023.02.26
'CS 이론/알고리즘' 카테고리의 다른 글
  • 4195번(유니온 파인드)
  • 17352번 (유니온파인드)
  • 11404번(플로이드 워셜)
  • 1956번(플로이드 워셜)
Bello's
Bello's
개발하는 벨로
  • Bello's
    벨로의 개발일지
    Bello's
  • 전체
    오늘
    어제
    • 분류 전체보기 (199) N
      • 노예 일지 (7)
        • 스타트업 노예일지 (3)
      • CS 이론 (81)
        • 학과 수업 (4)
        • 알고리즘 (64)
        • 시스템 프로그래밍 (3)
        • 데이터 통신 (1)
        • 운영체제 (2)
        • 데이터베이스 (1)
      • project (3)
      • 나는 감자다. (4)
      • Spring (27)
      • 모각코 (45)
        • 절개와지조(모각코) (7)
        • 어쩌다보니 박준태가 조장이조 (11)
        • 어쩌다보니 박준태가 또 조장이조 (12)
      • LikeLion🦁 (20)
      • 캘리포니아 감자 (4)
      • OpenSource Contribute (1)
      • 우아한테크벨로 (1) N
        • 프리코스 회고록 (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    8기
    뛰슈
    절개와지조
    오블완
    회고록
    누적합
    JPA
    Spring
    모각코
    그래프 순회
    DFS
    프리코스
    백준
    어렵다
    자바
    티스토리챌린지
    BFS
    나는 감자
    감자
    타임리프
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
Bello's
11505번
상단으로

티스토리툴바