문제 링크 : https://www.acmicpc.net/problem/10999
레이지 세그먼트 트리를 사용한 풀이이다.
레이지 세그먼트 트리와 관련된 함수들을 구현하고 입력을 받아 넣기만 하면 된다.
다만, d를 선언할 때 long long이 아닌 int로 선언을 하게 되면 범위를 초과하게 되어 틀렸다고 뜨기 때문에 그 부분을 조심해야 한다.
#include <bits/stdc++.h>
using namespace std;
const int MAX = 1000000;
long long tree[MAX * 4 + 100];
long long lazy[MAX * 4 + 100];
long long a[MAX + 10];
void propagation(int node, int s, int e) {
if (lazy[node] == 0) return;
tree[node] += lazy[node] * (e - s + 1);
if (s != e) {
lazy[node * 2] += lazy[node];
lazy[node * 2 + 1] += lazy[node];
}
lazy[node] = 0;
}
void init(int node, int s, int e){
if (s == e){
tree[node] = a[s];
return;
}
int mid = (s + e) / 2;
init(node * 2, s, mid);
init(node * 2 + 1, mid + 1, e);
tree[node] = tree[node * 2] + tree[node * 2 + 1];
}
long long query(int node, int s, int e, int l, int r) {
propagation(node,s,e);
if(r < s || e < l) return 0;
if(l <= s && e <= r) return tree[node];
int mid = (s + e) / 2;
long long left = query(node * 2, s, mid, l, r);
long long right = query(node * 2 + 1, mid + 1, e, l, r);
return left + right;
}
void update(int node, int s, int e, int l, int r, long long x) {
propagation(node, s, e);
if (r < s || e < l) return;
if (l <= s && e <= r) {
lazy[node] += x;
propagation(node, s, e);
return;
}
int mid = (s + e) / 2;
update(node * 2, s, mid, l, r, x);
update(node * 2 + 1, mid + 1, e, l, r, x);
tree[node] = tree[node * 2] + tree[node * 2 + 1];
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n,m,k;
// n : 수의 개수
// m : 수의 변경이 일어나는 횟수
// k : 구간의 합을 구하는 횟수
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
init(1,1,n);
for (int i = 0; i < m + k; i++) {
int a;
cin >> a;
if (a == 1){
int b,c;
long long d;
cin >> b >> c >> d;
update(1,1,n,b,c,d);
} else {
int b,c;
cin >> b >> c;
cout << query(1,1,n,b,c) << '\n';
}
}
return 0;
}