Skip to content

Commit 734b93d

Browse files
authored
Merge pull request #1290 from AlgorithmWithGod/khj20006
[20251101] BOJ / D5 / Hierarchical Structure / 권혁준
2 parents a84c41b + c6541df commit 734b93d

File tree

1 file changed

+201
-0
lines changed

1 file changed

+201
-0
lines changed
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
```java
2+
import java.io.*;
3+
import java.util.*;
4+
5+
class IOController {
6+
BufferedReader br;
7+
BufferedWriter bw;
8+
StringTokenizer st;
9+
10+
public IOController() {
11+
br = new BufferedReader(new InputStreamReader(System.in));
12+
bw = new BufferedWriter(new OutputStreamWriter(System.out));
13+
st = new StringTokenizer("");
14+
}
15+
16+
String nextLine() throws Exception {
17+
String line = br.readLine();
18+
st = new StringTokenizer(line);
19+
return line;
20+
}
21+
22+
String nextToken() throws Exception {
23+
while (!st.hasMoreTokens())
24+
nextLine();
25+
return st.nextToken();
26+
}
27+
28+
int nextInt() throws Exception {
29+
return Integer.parseInt(nextToken());
30+
}
31+
32+
long nextLong() throws Exception {
33+
return Long.parseLong(nextToken());
34+
}
35+
36+
double nextDouble() throws Exception {
37+
return Double.parseDouble(nextToken());
38+
}
39+
40+
void close() throws Exception {
41+
bw.flush();
42+
bw.close();
43+
}
44+
45+
void write(String content) throws Exception {
46+
bw.write(content);
47+
}
48+
49+
}
50+
51+
class SegTree {
52+
int size;
53+
long[] tree;
54+
SegTree(int size) {
55+
this.size = size;
56+
tree = new long[size*4];
57+
}
58+
59+
void upt(int s, int e, int i, int v, int n) {
60+
if(s == e) {
61+
tree[n] += v;
62+
return;
63+
}
64+
int m = (s+e)>>1;
65+
if(i <= m) upt(s,m,i,v,n*2);
66+
else upt(m+1,e,i,v,n*2+1);
67+
tree[n] = tree[n*2] + tree[n*2+1];
68+
}
69+
70+
long sum(int s, int e, int l, int r, int n) {
71+
if(l>r || l>e || r<s) return 0;
72+
if(l<=s && e<=r) return tree[n];
73+
int m = (s+e)>>1;
74+
return sum(s,m,l,r,n*2) + sum(m+1,e,l,r,n*2+1);
75+
}
76+
}
77+
78+
public class Main {
79+
80+
static IOController io;
81+
82+
//
83+
84+
static int N, Q, root, cnt = 0;
85+
static SegTree seg;
86+
static TreeSet<Integer> lower;
87+
static int[][] events, infos, queries;
88+
static List<Integer>[] graph, chain;
89+
static int[] sz, par, dep, cn, ci, ord;
90+
static long[] ans;
91+
92+
static void dfs(int n, int p) {
93+
sz[n] = 1;
94+
par[n] = p;
95+
for(int i:graph[n]) {
96+
dfs(i,n);
97+
sz[n] += sz[i];
98+
}
99+
}
100+
101+
static void hld(int n, int p, int s, int d) {
102+
dep[n] = d;
103+
cn[n] = s;
104+
ci[n] = chain[s].size();
105+
chain[s].add(n);
106+
ord[n] = ++cnt;
107+
int h = -1;
108+
for(int i:graph[n]) if(h == -1 || sz[i] > sz[h]) h = i;
109+
if(h != -1) hld(h,n,s,d);
110+
for(int i:graph[n]) if(i != h) hld(i,n,i,d+1);
111+
}
112+
113+
public static void main(String[] args) throws Exception {
114+
115+
io = new IOController();
116+
117+
N = io.nextInt();
118+
Q = io.nextInt();
119+
120+
infos = new int[N][];
121+
for(int i=1;i<=N;i++) infos[i-1] = new int[]{io.nextInt(),i};
122+
Arrays.sort(infos, (a,b) -> a[0]==b[0] ? a[1]-b[1] : a[0]-b[0]);
123+
124+
graph = new List[N+1];
125+
lower = new TreeSet<>();
126+
for(int i=1;i<=N;i++) lower.add(i);
127+
for(int i=1;i<=N;i++) graph[i] = new ArrayList<>();
128+
for(int i=1;i<N;i++) {
129+
int a = io.nextInt();
130+
int b = io.nextInt();
131+
graph[a].add(b);
132+
lower.remove(b);
133+
}
134+
root = lower.higher(0);
135+
136+
events = new int[2*Q][];
137+
queries = new int[Q][];
138+
for(int i=0;i<Q;i++) {
139+
int a = io.nextInt();
140+
int b = io.nextInt();
141+
int l = io.nextInt();
142+
int r = io.nextInt();
143+
events[i*2] = new int[]{l, i, -1};
144+
events[i*2+1] = new int[]{r+1, i, 1};
145+
queries[i] = new int[]{a,b,l,r};
146+
}
147+
Arrays.sort(events, (a,b) -> a[0]==b[0] ? a[1]-b[1] : a[0]-b[0]);
148+
149+
sz = new int[N+1];
150+
par = new int[N+1];
151+
dep = new int[N+1];
152+
cn = new int[N+1];
153+
ci = new int[N+1];
154+
ord = new int[N+1];
155+
chain = new List[N+1];
156+
for(int i=1;i<=N;i++) chain[i] = new ArrayList<>();
157+
dfs(root,0);
158+
hld(root,0,root,0);
159+
160+
ans = new long[N];
161+
seg = new SegTree(N+1);
162+
int pos = 0;
163+
for(int[] event : events) {
164+
int value = event[0], queryIdx = event[1], coef = event[2];
165+
while(pos < N && infos[pos][0] < value) {
166+
seg.upt(1,N,ord[infos[pos][1]], infos[pos][0], 1);
167+
pos++;
168+
}
169+
170+
int a = queries[queryIdx][0];
171+
int b = queries[queryIdx][1];
172+
while(cn[a] != cn[b]) {
173+
if(dep[a] > dep[b]) {
174+
long sum = seg.sum(1,N,ord[cn[a]],ord[a],1);
175+
ans[queryIdx] += sum * coef;
176+
a = par[cn[a]];
177+
}
178+
else {
179+
long sum = seg.sum(1,N,ord[cn[b]],ord[b],1);
180+
ans[queryIdx] += sum * coef;
181+
b = par[cn[b]];
182+
}
183+
}
184+
if(ci[a] > ci[b]) {
185+
long sum = seg.sum(1,N,ord[b],ord[a],1);
186+
ans[queryIdx] += sum * coef;
187+
}
188+
else {
189+
long sum = seg.sum(1,N,ord[a],ord[b],1);
190+
ans[queryIdx] += sum * coef;
191+
}
192+
}
193+
194+
for(int i=0;i<Q;i++) io.write(ans[i] + "\n");
195+
196+
io.close();
197+
198+
}
199+
200+
}
201+
```

0 commit comments

Comments
 (0)