PS/Problems
[Java] 백준 10999번 합 구하기 - Lazy Segment Tree
CalicoCat22
2022. 3. 15. 14:04
https://www.acmicpc.net/problem/10999
10999번: 구간 합 구하기 2
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이고, K는 구간의 합을 구하는 횟수이다. 그리고 둘째 줄부터 N+1번째 줄
www.acmicpc.net
import java.util.*;
import java.io.*;
public class p5_10999 {
static FastScanner fs = new FastScanner();
static PrintWriter pw = new PrintWriter(System.out);
static int n, m;
static long[] val, tree, lazy;
public static void main(String[] args) {
n = fs.nextInt();
m = fs.nextInt() + fs.nextInt();
val = new long[n + 1];
tree = new long[n * 4];
lazy = new long[n * 4];
for (int i=1;i<=n;i++) val[i] = fs.nextLong();
init(1, n, 1);
while (m-- > 0){
int flag = fs.nextInt();
if (flag == 1){
int left = fs.nextInt(), right = fs.nextInt();
long value = fs.nextLong();
update(1, n, 1, left, right, value);
}
else{
int left = fs.nextInt(), right = fs.nextInt();
pw.println(sum(1, n, 1, left, right));
}
}
pw.close();
}
static void update(int lo, int hi, int node, int left, int right, long value){
lazy(lo, hi, node);
if (hi < left || right < lo) return;
if (left <= lo && hi <= right){
tree[node] += (hi - lo + 1) * value;
if (lo != hi){
lazy[node * 2] += value;
lazy[node * 2 + 1] += value;
}
return;
}
int mid = (lo + hi) / 2;
update(lo, mid, node * 2, left, right, value);
update(mid + 1, hi, node * 2 + 1, left, right, value);
tree[node] = tree[node * 2] + tree[node * 2 + 1];
}
static void lazy(int lo, int hi, int node){
if (lazy[node] != 0){
tree[node] += lazy[node] * (hi - lo + 1);
if (lo != hi){
lazy[node * 2] += lazy[node];
lazy[node * 2 + 1] += lazy[node];
}
lazy[node] = 0;
}
}
static long sum(int lo, int hi, int node, int left, int right){
lazy(lo, hi, node);
if (hi < left || right < lo) return 0;
if (left <= lo && hi <= right) return tree[node];
int mid = (lo + hi) / 2;
return sum(lo, mid, node * 2, left, right) + sum(mid + 1, hi, node * 2 + 1, left, right);
}
static long init(int left, int right, int node){
if (left == right) return tree[node] = val[left];
int mid = (left + right) / 2;
return tree[node] = init(left, mid, node * 2) + init(mid + 1, right, node * 2 + 1);
}
// ----------input function----------
static void sort(int[] a) {
ArrayList<Integer> L = new ArrayList<>();
for (int i : a)
L.add(i);
Collections.sort(L);
for (int i = 0; i < a.length; i++)
a[i] = L.get(i);
}
static class FastScanner {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer("");
String next() {
while (!st.hasMoreTokens()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
int[] readArray(int n) {
int[] a = new int[n];
for (int i = 0; i < n; i++)
a[i] = nextInt();
return a;
}
long nextLong() {
return Long.parseLong(next());
}
}
}