Skip to content

Commit fa1ef38

Browse files
authored
[20250424] BOJ / D5 / 금광 / 신희을
1 parent f42927b commit fa1ef38

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
```java
2+
import java.util.*;
3+
import java.io.*;
4+
5+
class Main {
6+
7+
static Node[] segments;
8+
static long MIN = Long.MIN_VALUE >> 1;
9+
static Node DEFAULT = new Node(MIN,MIN,MIN,0);
10+
static int N;
11+
static int size;
12+
public static void main(String[] args) throws Exception {
13+
14+
N = read();
15+
16+
size = 1;
17+
18+
while(size < N) size <<= 1;
19+
20+
21+
22+
// Point 별로 값을 저장해두고, x좌표 순으로 정렬 후 index 매기기
23+
Point[] arr = new Point[N];
24+
25+
for(int i = 0; i < N; i++) arr[i] = new Point(read(), read(), 0, read());
26+
27+
Arrays.sort(arr, (o1, o2) -> {
28+
if(o1.x == o2.x) return o1.val - o2.val;
29+
return o1.x - o2.x;
30+
});
31+
32+
for(int i = 0; i < N; i++) {
33+
arr[i].index = i;
34+
int idx = i;
35+
while((i + 1) < N && arr[i + 1].x == arr[i].x) {
36+
arr[i + 1].index = idx;
37+
i++;
38+
}
39+
}
40+
// 이후 y좌표 순으로 정렬 후
41+
Arrays.sort(arr, Comparator.comparingInt(p -> p.y));
42+
43+
// y가 작은 것/큰 것부터 update하면서 해당 인덱스에 업데이트
44+
long max = Long.MIN_VALUE;
45+
46+
47+
48+
int nxt = 1;
49+
for(int k = 0; k < N; k+=nxt) {
50+
nxt = 1;
51+
while((k+nxt) < N && arr[k+nxt].y == arr[k].y) {
52+
nxt++;
53+
}
54+
segments = new Node[(size << 1) + 1];
55+
Arrays.fill(segments, DEFAULT);
56+
for (int i = k; i < N; i++) {
57+
Point point = arr[i];
58+
update(point.index, point.val);
59+
60+
// y가 같은 값이라면 한번에 업데이트 해야 함.
61+
while ((i + 1) < N && arr[i + 1].y == point.y) {
62+
update(arr[i + 1].index, arr[i + 1].val);
63+
i++;
64+
}
65+
max = Math.max(max, segments[2].max);
66+
}
67+
}
68+
69+
System.out.println(max);
70+
}
71+
72+
public static void update(int idx, int val) {
73+
74+
idx += size + 1;
75+
if(segments[idx] == DEFAULT) segments[idx] = new Node(val, val, val, val);
76+
else {
77+
segments[idx].lmax += val;
78+
segments[idx].rmax += val;
79+
segments[idx].max += val;
80+
segments[idx].sum += val;
81+
}
82+
idx = (idx + 1) >> 1;
83+
84+
while(idx >= 2) {
85+
segments[idx] = combine(segments[(idx << 1) - 1], segments[idx << 1]);
86+
idx = (idx + 1) >> 1;
87+
}
88+
}
89+
90+
public static Node combine(Node lNode, Node rNode) {
91+
return new Node(
92+
Math.max(lNode.lmax, lNode.sum + rNode.lmax),
93+
Math.max(rNode.rmax, rNode.sum + lNode.rmax),
94+
Math.max(lNode.rmax + rNode.lmax, Math.max(lNode.max, rNode.max)),
95+
lNode.sum + rNode.sum
96+
);
97+
}
98+
99+
public static class Point {
100+
int x;
101+
int y;
102+
int index;
103+
int val;
104+
105+
public Point(int x, int y, int index, int val) {
106+
this.x = x;
107+
this.y = y;
108+
this.index = index;
109+
this.val = val;
110+
}
111+
}
112+
113+
public static class Node {
114+
long lmax;
115+
long rmax;
116+
long max;
117+
long sum;
118+
119+
public Node(long lmax, long rmax, long max, long sum) {
120+
this.lmax = lmax;
121+
this.rmax = rmax;
122+
this.max = max;
123+
this.sum = sum;
124+
}
125+
126+
}
127+
128+
private static int read() throws Exception {
129+
int d, o;
130+
boolean negative = false;
131+
d = System.in.read();
132+
if (d == 45) {
133+
negative = true;
134+
d = System.in.read();
135+
}
136+
137+
o = d & 15;
138+
while ((d = System.in.read()) > 32)
139+
o = (o << 3) + (o << 1) + (d & 15);
140+
141+
return negative ? -o : o;
142+
}
143+
144+
}
145+
```

0 commit comments

Comments
 (0)