Skip to content

Commit 8fdc026

Browse files
authored
Merge pull request #317 from AlgorithmWithGod/ShinHeeEul
[20250423] BOJ / P1 / 연속합과 쿼리 / 신희을
2 parents b6b11ee + f42927b commit 8fdc026

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
```java
2+
import java.util.*;
3+
import java.io.*;
4+
5+
class Main {
6+
7+
8+
static Node[] segments;
9+
static int N;
10+
static int size;
11+
static int MIN = Integer.MIN_VALUE >> 1;
12+
static Node DEFAULT = new Node(MIN,MIN,MIN,0);
13+
public static void main(String[] args) throws Exception {
14+
15+
16+
N = read();
17+
size = 1;
18+
19+
while(size < N) {
20+
size <<= 1;
21+
22+
}
23+
24+
segments = new Node[(size << 1) + 1];
25+
26+
for(int i = size + 1; i < size + N + 1; i++) {
27+
int a = read();
28+
segments[i] = new Node(a, a, a, a);
29+
}
30+
31+
for(int i = size + N + 1; i < (size << 1) + 1; i++) segments[i] = DEFAULT;
32+
33+
init();
34+
35+
int M = read();
36+
StringBuilder sb = new StringBuilder();
37+
while(M-->0) {
38+
Node node = query(read(), read(), 2, 1, size);
39+
sb.append(node.max).append("\n");
40+
}
41+
System.out.println(sb);
42+
}
43+
44+
public static Node query(int left, int right, int node, int start, int end) {
45+
if(end < left || right < start) return DEFAULT;
46+
47+
if(left <= start && end <= right) {
48+
return segments[node];
49+
}
50+
51+
int mid = (start + end) >> 1;
52+
Node leftNode = query(left, right, (node << 1) - 1, start, mid);
53+
Node rightNode = query(left, right, node << 1, mid + 1, end);
54+
return new Node(Math.max(leftNode.lmax, leftNode.sum + rightNode.lmax),
55+
Math.max(rightNode.rmax, rightNode.sum + leftNode.rmax),
56+
Math.max(leftNode.max, Math.max(rightNode.max, leftNode.rmax + rightNode.lmax)),
57+
leftNode.sum + rightNode.sum);
58+
59+
}
60+
61+
public static void init() {
62+
63+
int segmentSize = size << 1;
64+
65+
while(segmentSize > 2) {
66+
Node leftNode = segments[segmentSize - 1];
67+
Node rightNode = segments[segmentSize];
68+
// 범위 내의 제일 좌측 노드를 포함하는 연속합은?
69+
// (왼쪽 자식의 leftMax), (왼쪽 자식의 sum) + (우측 자식 노드의 leftMax)
70+
71+
// 범위 내의 제일 우측 노드를 포함하는 연속합은?
72+
// (우측 자식의 rightMax), (우측 자식의 sum) + (좌측 자식 노드의 rightMax)
73+
74+
// 범위 내의 최대 합은?
75+
// (왼쪽 자식의 leftMax), (우측 자식의 rightMax), (왼쪽 자식의 rightMax + 우측 자식의 leftMax)
76+
77+
segments[segmentSize >> 1] = new Node(
78+
Math.max(leftNode.lmax, leftNode.sum + rightNode.lmax),
79+
Math.max(rightNode.rmax, rightNode.sum + leftNode.rmax),
80+
Math.max(leftNode.max, Math.max(rightNode.max, (leftNode.rmax + rightNode.lmax))),
81+
leftNode.sum + rightNode.sum
82+
);
83+
segmentSize -= 2;
84+
}
85+
86+
}
87+
88+
static class Node {
89+
// 범위 내의 제일 좌측 노드를 포함하는 최대 연속합
90+
int lmax;
91+
// 범위 내의 제일 우측 노드를 포함하는 최대 연속합
92+
int rmax;
93+
// 범위 내의 최대 연속합
94+
int max;
95+
// 구간 합
96+
int sum;
97+
98+
public Node(int leftMax, int rightMax, int max, int sum) {
99+
this.lmax = leftMax;
100+
this.rmax = rightMax;
101+
this.max = max;
102+
this.sum = sum;
103+
104+
}
105+
}
106+
107+
private static int read() throws Exception {
108+
int c;
109+
int n = 0;
110+
boolean negative = false;
111+
112+
while ((c = System.in.read()) <= 32) {
113+
if (c == -1) return -1;
114+
}
115+
116+
if (c == '-') {
117+
negative = true;
118+
c = System.in.read();
119+
}
120+
121+
do {
122+
n = n * 10 + (c - '0');
123+
c = System.in.read();
124+
} while (c > 32);
125+
126+
return negative ? -n : n;
127+
}
128+
129+
}
130+
```

0 commit comments

Comments
 (0)