728x90

 

11505번: 구간 곱 구하기

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

www.acmicpc.net

 

구간 합 구하기와 비슷한 방식으로 세그먼트 트리를 사용하면 될 것이라 생각했다.

 

각 tree의 값을 곱으로 계산하면 될 것이라 생각했지만, 

 

구간 합 구하기에서는 이전에 저장되어있던 수와 새로 바뀌는 수의 차이(diff)를 구해서 변경했지만,

 

곱에서는 0이 들어갈 경우 같은 방식으로 계산이 불가능 했다.

 

그래서 새로 값이 바뀔 경우 update에서 start == end라면 배열의 새로운 값을 넣고

 

아닐경우 start~mid, mid+1~end 구간으로 나누어서 쪼개 내려갔다.

 

세그먼트 트리를 알고있다면 쉽게 풀 수 있는 문제라고 생각된다.

 

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
import sys
import math
 
def init_tree(start, end, index):
    if start == end:
        tree[index] = arr[start]
    else:
        mid = (start + end) // 2
        tree[index] = init_tree(start, mid, 2*index) * init_tree(mid+1, end, 2*index + 1) % 1000000007
    return tree[index]
 
def find_mul(start, end, index, left, right):
    if left > end or right < start:
        return 1
    if left <= start and end <= right:
        return tree[index]
 
    mid = (start + end) // 2
    return find_mul(start, mid, 2*index, left, right) * find_mul(mid+1, end, 2*index + 1, left, right) % 1000000007
 
def update_tree(start, end, index, where, diff):
    if where < start or end < where:
        return
 
    if start == end:
        tree[index] = diff
    else:
        mid = (start + end) // 2
        update_tree(start, mid, index*2, where, diff)
        update_tree(mid+1, end, index*2 + 1, where, diff)
        tree[index] = tree[2*index] * tree[2*index + 1] % 1000000007
 
N, M, K = map(int, sys.stdin.readline().split())
arr = [int(sys.stdin.readline()) for _ in range(N)]
tree = [0* (1 << (int(math.ceil(math.log2(N))) + 1))
init_tree(0, N-11)
 
for _ in range(M + K):
    a, b, c = map(int, sys.stdin.readline().split())
 
    if a == 1# 수 변경
        update_tree(0, N-11, b-1, c)
 
    else# elif a == 2: # 구간 곱 구하기
        print(find_mul(0, N-11, b-1, c-1))
cs
728x90