Skip to content

Commit de8c65d

Browse files
committed
modify code
1 parent a39b619 commit de8c65d

File tree

3 files changed

+338
-10
lines changed

3 files changed

+338
-10
lines changed

src/class183/Code03_Race1.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ public class Code03_Race1 {
3434

3535
public static int[] dp = new int[MAXK];
3636

37-
// java的实现,getCentroid方法、getPath方法改成迭代才能通过,C++的实现不需要改动
38-
// 讲解118,讲了如何把递归函数改成迭代
37+
// 讲解118,递归函数改成迭代所需要的栈
3938
public static int[][] stack = new int[MAXN][5];
4039
public static int stacksize, u, f, sum, edge, e;
4140

src/class183/Code04_Game1.java

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/class183/Code04_Maschera1.java

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
package class183;
2+
3+
// 道路魔力总和,java版
4+
// 测试链接 : https://www.luogu.com.cn/problem/P5351
5+
// 提交以下的code,提交时请把类名改成"Main",可以通过所有测试用例
6+
7+
import java.io.IOException;
8+
import java.io.InputStream;
9+
import java.io.OutputStreamWriter;
10+
import java.io.PrintWriter;
11+
12+
public class Code04_Maschera1 {
13+
14+
public static int MAXN = 100001;
15+
public static int n, l, r, total;
16+
17+
public static int[] head = new int[MAXN];
18+
public static int[] nxt = new int[MAXN << 1];
19+
public static int[] to = new int[MAXN << 1];
20+
public static int[] weight = new int[MAXN << 1];
21+
public static int cntg;
22+
23+
public static int[] tree = new int[MAXN];
24+
25+
public static boolean[] vis = new boolean[MAXN];
26+
public static int[] siz = new int[MAXN];
27+
public static int[] maxPart = new int[MAXN];
28+
public static int centroid;
29+
30+
public static int[] allMaxv = new int[MAXN];
31+
public static int[] allEdge = new int[MAXN];
32+
public static int cnta;
33+
34+
public static int[] curMaxv = new int[MAXN];
35+
public static int[] curEdge = new int[MAXN];
36+
public static int cntc;
37+
38+
public static long ans;
39+
40+
// 讲解118,递归函数改成迭代所需要的栈
41+
public static int[][] stack = new int[MAXN][5];
42+
public static int stacksize, u, f, maxv, edge, e;
43+
44+
public static void push(int u, int f, int maxv, int edge, int e) {
45+
stack[stacksize][0] = u;
46+
stack[stacksize][1] = f;
47+
stack[stacksize][2] = maxv;
48+
stack[stacksize][3] = edge;
49+
stack[stacksize][4] = e;
50+
stacksize++;
51+
}
52+
53+
public static void pop() {
54+
--stacksize;
55+
u = stack[stacksize][0];
56+
f = stack[stacksize][1];
57+
maxv = stack[stacksize][2];
58+
edge = stack[stacksize][3];
59+
e = stack[stacksize][4];
60+
}
61+
62+
public static void addEdge(int u, int v, int w) {
63+
nxt[++cntg] = head[u];
64+
to[cntg] = v;
65+
weight[cntg] = w;
66+
head[u] = cntg;
67+
}
68+
69+
public static int lowbit(int i) {
70+
return i & -i;
71+
}
72+
73+
public static void add(int i, int v) {
74+
while (i <= r) {
75+
tree[i] += v;
76+
i += lowbit(i);
77+
}
78+
}
79+
80+
public static int sum(int i) {
81+
int ret = 0;
82+
while (i > 0) {
83+
ret += tree[i];
84+
i -= lowbit(i);
85+
}
86+
return ret;
87+
}
88+
89+
// 找重心的递归版,java会爆栈,C++可以通过
90+
public static void getCentroid1(int u, int fa) {
91+
siz[u] = 1;
92+
maxPart[u] = 0;
93+
for (int e = head[u]; e > 0; e = nxt[e]) {
94+
int v = to[e];
95+
if (v != fa && !vis[v]) {
96+
getCentroid1(v, u);
97+
siz[u] += siz[v];
98+
maxPart[u] = Math.max(siz[v], maxPart[u]);
99+
}
100+
}
101+
maxPart[u] = Math.max(maxPart[u], total - siz[u]);
102+
if (centroid == 0 || maxPart[u] < maxPart[centroid]) {
103+
centroid = u;
104+
}
105+
}
106+
107+
// 找重心的迭代版
108+
public static void getCentroid2(int cur, int fa) {
109+
stacksize = 0;
110+
push(cur, fa, 0, 0, -1);
111+
while (stacksize > 0) {
112+
pop();
113+
if (e == -1) {
114+
siz[u] = 1;
115+
maxPart[u] = 0;
116+
e = head[u];
117+
} else {
118+
e = nxt[e];
119+
}
120+
if (e != 0) {
121+
push(u, f, 0, 0, e);
122+
int v = to[e];
123+
if (v != f && !vis[v]) {
124+
push(to[e], u, 0, 0, -1);
125+
}
126+
} else {
127+
for (int ei = head[u]; ei > 0; ei = nxt[ei]) {
128+
int v = to[ei];
129+
if (v != f && !vis[v]) {
130+
siz[u] += siz[v];
131+
maxPart[u] = Math.max(siz[v], maxPart[u]);
132+
}
133+
}
134+
maxPart[u] = Math.max(maxPart[u], total - siz[u]);
135+
if (centroid == 0 || maxPart[u] < maxPart[centroid]) {
136+
centroid = u;
137+
}
138+
}
139+
}
140+
}
141+
142+
// 收集路径的递归版,java会爆栈,C++可以通过
143+
public static void getPath1(int u, int fa, int maxv, int edge) {
144+
if (edge > r) {
145+
return;
146+
}
147+
curMaxv[++cntc] = maxv;
148+
curEdge[cntc] = edge;
149+
for (int e = head[u]; e > 0; e = nxt[e]) {
150+
int v = to[e];
151+
if (v != fa && !vis[v]) {
152+
getPath1(v, u, Math.max(maxv, weight[e]), edge + 1);
153+
}
154+
}
155+
}
156+
157+
// 收集路径的迭代版
158+
public static void getPath2(int cur, int fa, int pmaxv, int pedge) {
159+
stacksize = 0;
160+
push(cur, fa, pmaxv, pedge, -1);
161+
while (stacksize > 0) {
162+
pop();
163+
if (e == -1) {
164+
if (edge > r) {
165+
continue;
166+
}
167+
curMaxv[++cntc] = maxv;
168+
curEdge[cntc] = edge;
169+
e = head[u];
170+
} else {
171+
e = nxt[e];
172+
}
173+
if (e != 0) {
174+
push(u, f, maxv, edge, e);
175+
int v = to[e];
176+
if (v != f && !vis[v]) {
177+
push(to[e], u, Math.max(maxv, weight[e]), edge + 1, -1);
178+
}
179+
}
180+
}
181+
}
182+
183+
public static void sort(int[] maxv, int[] edge, int l, int r) {
184+
if (l >= r) return;
185+
int i = l, j = r, pv = maxv[(l + r) >> 1], pe = edge[(l + r) >> 1], tmp;
186+
while (i <= j) {
187+
while (maxv[i] < pv || (maxv[i] == pv && edge[i] < pe)) i++;
188+
while (maxv[j] > pv || (maxv[j] == pv && edge[j] > pe)) j--;
189+
if (i <= j) {
190+
tmp = maxv[i]; maxv[i] = maxv[j]; maxv[j] = tmp;
191+
tmp = edge[i]; edge[i] = edge[j]; edge[j] = tmp;
192+
i++; j--;
193+
}
194+
}
195+
sort(maxv, edge, l, j);
196+
sort(maxv, edge, i, r);
197+
}
198+
199+
public static void calc(int u) {
200+
cnta = 0;
201+
for (int e = head[u]; e > 0; e = nxt[e]) {
202+
int v = to[e];
203+
if (!vis[v]) {
204+
cntc = 0;
205+
// getPath1(v, u, weight[e], 1);
206+
getPath2(v, u, weight[e], 1);
207+
if (cntc > 0) {
208+
sort(curMaxv, curEdge, 1, cntc);
209+
for (int i = 1; i <= cntc; i++) {
210+
int maxv = curMaxv[i];
211+
int edge = curEdge[i];
212+
int left = l - edge - 1;
213+
int right = r - edge;
214+
if (right >= 0) {
215+
left = Math.max(left, 0);
216+
right = Math.min(right, r);
217+
if (left <= right) {
218+
ans -= 1L * maxv * (sum(right) - sum(left));
219+
}
220+
}
221+
add(edge, 1);
222+
}
223+
for (int i = 1; i <= cntc; i++) {
224+
add(curEdge[i], -1);
225+
}
226+
for (int i = 1; i <= cntc; i++) {
227+
allMaxv[++cnta] = curMaxv[i];
228+
allEdge[cnta] = curEdge[i];
229+
}
230+
}
231+
}
232+
}
233+
if (cnta > 0) {
234+
sort(allMaxv, allEdge, 1, cnta);
235+
for (int i = 1; i <= cnta; i++) {
236+
int maxv = allMaxv[i];
237+
int edge = allEdge[i];
238+
int left = l - edge - 1;
239+
int right = r - edge;
240+
if (right >= 0) {
241+
left = Math.max(left, 0);
242+
right = Math.min(right, r);
243+
if (left <= right) {
244+
ans += 1L * maxv * (sum(right) - sum(left));
245+
}
246+
}
247+
add(edge, 1);
248+
}
249+
for (int i = 1; i <= cnta; i++) {
250+
add(allEdge[i], -1);
251+
}
252+
for (int i = 1; i <= cnta; i++) {
253+
if (allEdge[i] >= l) {
254+
ans += allMaxv[i];
255+
}
256+
}
257+
}
258+
}
259+
260+
public static void compute(int u) {
261+
calc(u);
262+
vis[u] = true;
263+
for (int e = head[u]; e > 0; e = nxt[e]) {
264+
int v = to[e];
265+
if (!vis[v]) {
266+
total = siz[v];
267+
centroid = 0;
268+
// getCentroid1(v, 0);
269+
getCentroid2(v, 0);
270+
compute(centroid);
271+
}
272+
}
273+
}
274+
275+
public static void main(String[] args) throws Exception {
276+
FastReader in = new FastReader(System.in);
277+
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
278+
n = in.nextInt();
279+
l = in.nextInt();
280+
r = in.nextInt();
281+
for (int i = 1, u, v, w; i < n; i++) {
282+
u = in.nextInt();
283+
v = in.nextInt();
284+
w = in.nextInt();
285+
addEdge(u, v, w);
286+
addEdge(v, u, w);
287+
}
288+
total = n;
289+
centroid = 0;
290+
// getCentroid1(1, 0);
291+
getCentroid2(1, 0);
292+
compute(centroid);
293+
out.println(ans << 1);
294+
out.flush();
295+
out.close();
296+
}
297+
298+
// 读写工具类
299+
static class FastReader {
300+
private final byte[] buffer = new byte[1 << 20];
301+
private int ptr = 0, len = 0;
302+
private final InputStream in;
303+
304+
FastReader(InputStream in) {
305+
this.in = in;
306+
}
307+
308+
private int readByte() throws IOException {
309+
if (ptr >= len) {
310+
len = in.read(buffer);
311+
ptr = 0;
312+
if (len <= 0)
313+
return -1;
314+
}
315+
return buffer[ptr++];
316+
}
317+
318+
int nextInt() throws IOException {
319+
int c;
320+
do {
321+
c = readByte();
322+
} while (c <= ' ' && c != -1);
323+
boolean neg = false;
324+
if (c == '-') {
325+
neg = true;
326+
c = readByte();
327+
}
328+
int val = 0;
329+
while (c > ' ' && c != -1) {
330+
val = val * 10 + (c - '0');
331+
c = readByte();
332+
}
333+
return neg ? -val : val;
334+
}
335+
}
336+
337+
}

0 commit comments

Comments
 (0)