Skip to content

Commit d10da6a

Browse files
authored
[20250407] BOJ / P3 / 수열과 쿼리 1 / 신희을
1 parent 95f4fc6 commit d10da6a

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
```java
2+
3+
import java.util.*;
4+
import java.io.*;
5+
6+
class Main {
7+
8+
static Node[] segments;
9+
static int N;
10+
static int size = 1;
11+
public static void main(String args[]) throws Exception {
12+
N = read();
13+
StringBuilder sb = new StringBuilder();
14+
while(size < N) size <<= 1;
15+
16+
segments = new Node[(size << 1) + 1];
17+
18+
// 머지 소트 트리 구성하고
19+
for(int i = size + 1 ; i < size + N + 1; i++) {
20+
segments[i] = new Node();
21+
segments[i].arr = new int[1];
22+
segments[i].arr[0] = read();
23+
}
24+
25+
for(int i = size + N + 1 ; i < (size << 1) + 1; i++) {
26+
segments[i] = new Node();
27+
segments[i].arr = new int[1];
28+
segments[i].arr[0] = 0;
29+
}
30+
int segmentSize = size << 1;
31+
32+
33+
while(segmentSize > 2) {
34+
merge(segments[segmentSize], segments[segmentSize - 1],
35+
segmentSize >> 1, segments[segmentSize].arr.length << 1);
36+
segmentSize -= 2;
37+
}
38+
// 해당 범위 내에 포함될 때 이분 탐색으로 값 탐색하기
39+
int M = read();
40+
41+
while(M --> 0) {
42+
sb.append(query(read(),read(),2,1, size, read())).append("\n");
43+
}
44+
45+
System.out.println(sb);
46+
}
47+
48+
public static void merge(Node left, Node right, int idx, int mergeSize) {
49+
segments[idx] = new Node();
50+
segments[idx].arr = new int[mergeSize];
51+
52+
// 좌측 인덱스, 우측 인덱스
53+
int leftIdx = 0;
54+
int rightIdx = 0;
55+
int end = (mergeSize >> 1);
56+
// 더 작은 값을 업데이트 하고 다음 인덱스로 옮기기
57+
for(int i = 0; i < mergeSize; i++) {
58+
//System.out.println(leftIdx + " " + rightIdx);
59+
if(rightIdx == end) {
60+
segments[idx].arr[i] = left.arr[leftIdx];
61+
leftIdx++;
62+
continue;
63+
}
64+
65+
if(leftIdx == end){
66+
segments[idx].arr[i] = right.arr[rightIdx];
67+
rightIdx++;
68+
continue;
69+
}
70+
int a = left.arr[leftIdx];
71+
int b = right.arr[rightIdx];
72+
if(a < b) {
73+
segments[idx].arr[i] = a;
74+
leftIdx++;
75+
continue;
76+
} else {
77+
segments[idx].arr[i] = b;
78+
rightIdx++;
79+
continue;
80+
}
81+
}
82+
}
83+
84+
public static int query(int left, int right, int node, int start, int end, int k) {
85+
86+
if(end < left || right < start) return 0;
87+
88+
if(left <= start && end <= right) {
89+
// 이분 탐색
90+
Node n = segments[node];
91+
int l = 0;
92+
int r = n.arr.length;
93+
94+
while(l < r) {
95+
int mid = (l + r) >> 1;
96+
if(n.arr[mid] > k) {
97+
r = mid;
98+
} else {
99+
l = mid + 1;
100+
}
101+
}
102+
return n.arr.length - l;
103+
}
104+
105+
int mid = (start + end) >> 1;
106+
return query(left, right, (node << 1) - 1, start, mid, k) + query(left, right, node << 1, mid + 1, end, k);
107+
108+
}
109+
110+
public static class Node {
111+
int[] arr;
112+
}
113+
114+
private static int read() throws Exception {
115+
int d, o;
116+
d = System.in.read();
117+
118+
o = d & 15;
119+
120+
while ((d = System.in.read()) > 32)
121+
o = (o << 3) + (o << 1) + (d & 15);
122+
123+
return o;
124+
}
125+
126+
127+
}
128+
```

0 commit comments

Comments
 (0)