알고리즘/백준
[백준/BOJ/11505] 구간 곱 구하기
코딩하는 회사원
2024. 1. 14. 11:03
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
세그먼트 트리이고, long long 처리에 유의해야 한다.
#include <iostream>
using namespace std;
typedef long long ll;
#define rint register int
const int MOD = 1e9+7;
const int MAX = 1e6+1;
int N,M,K,arr[MAX];
ll tree[MAX*3];
void init(int node,int start,int end){
if(start==end){
tree[node] = 1LL*arr[start];
}else{
init(node*2,start,(start+end)/2);
init(node*2+1,(start+end)/2+1,end);
tree[node] = (tree[node*2]*tree[node*2+1])%MOD;
}
}
void update(int node,int start,int end,int index,int change){
if(index < start || index > end) return;
if(start==end){
arr[index]=change;
tree[node]=1LL*change;
return;
}
update(node*2,start,(start+end)/2,index,change);
update(node*2+1,(start+end)/2+1,end,index,change);
tree[node] = (tree[node*2]*tree[node*2+1])%MOD;
}
ll query(int node,int start,int end,int left,int right){
if(left>end || right<start) return -1LL;
if(left<=start && end<=right) return tree[node];
ll lm = query(node*2,start,(start+end)/2,left,right);
ll rm = query(node*2+1,(start+end)/2+1,end,left,right);
if(lm==-1LL) return rm;
if(rm==-1LL) return lm;
return (lm*rm)%MOD;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin>>N>>M>>K;
for(rint i=1;i<=N;++i) cin>>arr[i];
init(1,1,N);
for(rint i=0;i<M+K;++i){
int a; cin>>a;
if(a==1){
int index,change;
cin>>index>>change;
update(1,1,N,index,change);
}else{
int left,right;
cin>>left>>right;
cout<<query(1,1,N,left,right)<<"\n";
}
}
return 0;
}
728x90