Skip to content

Commit 78549dc

Browse files
authored
[20250204] BOJ / 플래3 / 트리와 쿼리 2 / 권혁준
1 parent ec52f33 commit 78549dc

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
```java
2+
3+
import java.util.*;
4+
import java.io.*;
5+
6+
class Main {
7+
8+
// IO field
9+
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
10+
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
11+
static StringTokenizer st;
12+
13+
static void nextLine() throws Exception {st = new StringTokenizer(br.readLine());}
14+
static int nextInt() {return Integer.parseInt(st.nextToken());}
15+
static long nextLong() {return Long.parseLong(st.nextToken());}
16+
static void bwEnd() throws Exception {bw.flush();bw.close();}
17+
18+
// Additional field
19+
static int N;
20+
static int[] dep;
21+
static int[][] par;
22+
static long[][] dist;
23+
static int[][] cnt;
24+
static List<int[]>[] V;
25+
26+
static void initialize() {
27+
28+
V = new ArrayList[N+1];
29+
dep = new int[N+1];
30+
for(int i=1;i<=N;i++) V[i] = new ArrayList<>();
31+
par = new int[N+1][18];
32+
dist = new long[N+1][18];
33+
cnt = new int[N+1][18];
34+
35+
}
36+
37+
static void input() throws Exception {
38+
39+
N = Integer.parseInt(br.readLine());
40+
initialize();
41+
42+
for(int i=1;i<N;i++) {
43+
nextLine();
44+
int a = nextInt(), b = nextInt(), c = nextInt();
45+
V[a].add(new int[] {b,c});
46+
V[b].add(new int[] {a,c});
47+
}
48+
49+
}
50+
51+
static void dfs(int n, int p, int d) {
52+
par[n][0] = p;
53+
dep[n] = d;
54+
for(int[] x : V[n]) {
55+
if(x[0] == p) continue;
56+
dist[x[0]][0] = x[1];
57+
cnt[x[0]][0] = 1;
58+
dfs(x[0], n, d+1);
59+
}
60+
}
61+
62+
static void constructSparseTable() {
63+
for(int k=1;k<18;k++) {
64+
for(int i=1;i<=N;i++) {
65+
par[i][k] = par[par[i][k-1]][k-1];
66+
dist[i][k] = dist[par[i][k-1]][k-1] + dist[i][k-1];
67+
cnt[i][k] = cnt[par[i][k-1]][k-1] + cnt[i][k-1];
68+
}
69+
}
70+
}
71+
72+
static int lca(int u, int v) {
73+
while(dep[u] != dep[v]) {
74+
if(dep[u] > dep[v]) {
75+
int diff = dep[u] - dep[v];
76+
for(int i=0;i<18;i++) if((diff & (1<<i)) != 0) u = par[u][i];
77+
}
78+
else {
79+
int diff = dep[v] - dep[u];
80+
for(int i=0;i<18;i++) if((diff & (1<<i)) != 0) v = par[v][i];
81+
}
82+
}
83+
while(par[u][0] != par[v][0]) {
84+
for(int i=17;i>=0;i--) {
85+
if(par[u][i] != par[v][i]) {
86+
u = par[u][i];
87+
v = par[v][i];
88+
break;
89+
}
90+
}
91+
}
92+
93+
if(u != v) u = par[u][0];
94+
return u;
95+
96+
}
97+
98+
static long query1(int u, int v) {
99+
100+
long res = 0;
101+
int g = lca(u,v);
102+
int diff1 = dep[u] - dep[g], diff2 = dep[v] - dep[g];
103+
for(int i=0;i<18;i++) {
104+
if((diff1 & (1<<i)) != 0) {res += dist[u][i];u = par[u][i];}
105+
if((diff2 & (1<<i)) != 0) {res += dist[v][i];v = par[v][i];}
106+
}
107+
return res;
108+
109+
}
110+
111+
static int solve(int u, int v, int k) {
112+
k--;
113+
for(int i=0;i<18;i++) if((k & (1<<i)) != 0) u = par[u][i];
114+
return u;
115+
}
116+
117+
static int query2(int u, int v, int k) {
118+
119+
int g = lca(u,v);
120+
int diff = dep[u] - dep[g] + 1;
121+
if(k <= diff) return solve(u,g,k);
122+
k -= (diff-1);
123+
diff = dep[v] - dep[g] + 1;
124+
k = diff-k+1;
125+
return solve(v,g,k);
126+
127+
}
128+
129+
static void handleQuery() throws Exception {
130+
int Q = Integer.parseInt(br.readLine());
131+
while(Q-- > 0) {
132+
nextLine();
133+
int o = nextInt(), u = nextInt(), v = nextInt();
134+
if(o == 1) bw.write(query1(u,v)+"\n");
135+
else {
136+
int k = nextInt();
137+
bw.write(query2(u,v,k)+"\n");
138+
}
139+
}
140+
}
141+
142+
public static void main(String[] args) throws Exception {
143+
144+
input();
145+
dfs(1,0,0);
146+
constructSparseTable();
147+
handleQuery();
148+
149+
bwEnd();
150+
}
151+
152+
}
153+
154+
```

0 commit comments

Comments
 (0)