반응형
11505번: 구간 곱 구하기
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이고, K는 구간의 곱을 구하는 횟수이다. 그리고 둘째 줄부터 N+1번째 줄
www.acmicpc.net
세그먼트 트리
세그먼트 트리(Segment Tree) 구간 쿼리와 수정이 빈번하게 일어나는 상황에서 유용하게 사용할 수 있는 자료구조입니다. 배열의 특정 구간에 대한 정보를 빠르게 구하거나 업데이트할 때 사용되며
flrjtwjrjt.tistory.com
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
vector<long> tree;
static int MOD = 1000000007;
void SetTree(int i);
long GetMul(int s, int e);
void ChangeValue(int index, long value);
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N, M, K;
cin >> N >> M >> K;
int treeHeight = 0;
int Length = N;
while (Length > 0)
{
Length /= 2;
treeHeight++;
}
int treeSize = int(pow(2, treeHeight + 1));
int startNodeId = treeSize / 2 - 1;
tree.resize(treeSize + 1);
fill(tree.begin(), tree.end(), 1);
for (int i = startNodeId + 1; i <= startNodeId + N; i++)
{
cin >> tree[i];
}
SetTree(treeSize - 1);
for (int i = 0; i < M + K; i++)
{
long a, b, c;
cin >> a >> b >> c;
if (a == 1) {
ChangeValue(b + startNodeId, c);
}
else if (a == 2)
cout << GetMul(b + startNodeId, c + startNodeId) << "\n";
}
}
void ChangeValue(int index, long value)
{
tree[index] = value;
while (index > 1) {
index = index / 2;
tree[index] = tree[index * 2] % MOD * tree[index * 2 + 1] % MOD;
}
}
long GetMul(int s, int e)
{
long result = 1;
while (s <= e)
{
if (s % 2 == 1) {
result = result * tree[s] % MOD;
s++;
}
if (e % 2 == 0) {
result = result * tree[e] % MOD;
e--;
}
s /= 2;
e /= 2;
}
return result;
}
void SetTree(int index)
{
while (index != 1)
{
tree[index / 2] = tree[index / 2] * tree[index] % MOD;
index--;
}
}
반응형
LIST
'알고리즘 문제 > 백준' 카테고리의 다른 글
11438 LCA2 (최소 공통 조상) [Platinum V] (1) | 2024.04.26 |
---|---|
11437 LCA (최소 공통 조상) [Gold III] (0) | 2024.04.25 |
10868 최솟값 (세그먼트 트리)[Gold I] (0) | 2024.04.23 |
2024 구간 합 구하기 (세그먼트 트리) [Gold I] (0) | 2024.04.22 |
1991 트리 순회 (트리 순회)[Silver I] (0) | 2024.04.21 |