Skip to content

Commit 5bcf1ea

Browse files
committed
modify code
1 parent 1979f8c commit 5bcf1ea

File tree

2 files changed

+196
-22
lines changed

2 files changed

+196
-22
lines changed

src/class183/Code07_Maschera1.java

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package class183;
22

3-
// 所有路径的魔力和,java版
3+
// 所有合法路径的魔力和,java版
4+
// 一共有n个节点,给定n-1条边,每条边有边权,所有节点组成一棵树
5+
// 给定两个整数l、r,对于任意两个不同节点u、v,考虑它们之间的简单路径
6+
// 如果路径上边的数量在[l, r]范围内,则这条路径是合法路径
7+
// 路径的魔力值 = 路径上所有边权的最大值,打印所有合法路径的魔力和
8+
// 注意,u到v和v到u视为两条不同的路径,均要计入答案
9+
// 1 <= n、边权 <= 10^5
410
// 测试链接 : https://www.luogu.com.cn/problem/P5351
511
// 提交以下的code,提交时请把类名改成"Main",可以通过所有测试用例
612

@@ -12,7 +18,7 @@
1218
public class Code07_Maschera1 {
1319

1420
public static int MAXN = 100001;
15-
public static int n, minEdge, maxEdge;
21+
public static int n, l, r;
1622

1723
public static int[] head = new int[MAXN];
1824
public static int[] nxt = new int[MAXN << 1];
@@ -29,15 +35,12 @@ public class Code07_Maschera1 {
2935
public static int[] curMaxv = new int[MAXN];
3036
public static int[] curEdge = new int[MAXN];
3137
public static int cntc;
32-
3338
public static int[] allMaxv = new int[MAXN];
3439
public static int[] allEdge = new int[MAXN];
3540
public static int cnta;
3641

3742
public static int[] tree = new int[MAXN];
3843

39-
public static long ans;
40-
4144
// 讲解118,递归函数改成迭代所需要的栈
4245
public static int[][] stack = new int[MAXN][5];
4346
public static int stacksize, u, f, maxv, edge, e;
@@ -88,7 +91,7 @@ public static int lowbit(int i) {
8891
}
8992

9093
public static void add(int i, int v) {
91-
while (i <= maxEdge) {
94+
while (i <= r) {
9295
tree[i] += v;
9396
i += lowbit(i);
9497
}
@@ -158,7 +161,7 @@ public static void getCentroid2(int cur, int fa) {
158161

159162
// 收集信息递归版,java会爆栈,C++可以通过
160163
public static void dfs1(int u, int fa, int maxv, int edge) {
161-
if (edge > maxEdge) {
164+
if (edge > r) {
162165
return;
163166
}
164167
curMaxv[++cntc] = maxv;
@@ -178,7 +181,7 @@ public static void dfs2(int cur, int fa, int pmaxv, int pedge) {
178181
while (stacksize > 0) {
179182
pop();
180183
if (e == -1) {
181-
if (edge > maxEdge) {
184+
if (edge > r) {
182185
continue;
183186
}
184187
curMaxv[++cntc] = maxv;
@@ -197,7 +200,8 @@ public static void dfs2(int cur, int fa, int pmaxv, int pedge) {
197200
}
198201
}
199202

200-
public static void calc(int u) {
203+
public static long calc(int u) {
204+
long ans = 0;
201205
cnta = 0;
202206
for (int e = head[u]; e > 0; e = nxt[e]) {
203207
int v = to[e];
@@ -207,9 +211,7 @@ public static void calc(int u) {
207211
dfs2(v, u, weight[e], 1);
208212
sort(curMaxv, curEdge, 1, cntc);
209213
for (int i = 1; i <= cntc; i++) {
210-
int l = minEdge - curEdge[i] - 1;
211-
int r = maxEdge - curEdge[i];
212-
ans -= 1L * curMaxv[i] * (sum(r) - sum(l));
214+
ans -= 1L * curMaxv[i] * (sum(r - curEdge[i]) - sum(l - curEdge[i] - 1));
213215
add(curEdge[i], 1);
214216
}
215217
for (int i = 1; i <= cntc; i++) {
@@ -223,42 +225,42 @@ public static void calc(int u) {
223225
}
224226
sort(allMaxv, allEdge, 1, cnta);
225227
for (int i = 1; i <= cnta; i++) {
226-
int l = minEdge - allEdge[i] - 1;
227-
int r = maxEdge - allEdge[i];
228-
ans += 1L * allMaxv[i] * (sum(r) - sum(l));
228+
ans += 1L * allMaxv[i] * (sum(r - allEdge[i]) - sum(l - allEdge[i] - 1));
229229
add(allEdge[i], 1);
230230
}
231231
for (int i = 1; i <= cnta; i++) {
232232
add(allEdge[i], -1);
233233
}
234234
for (int i = 1; i <= cnta; i++) {
235-
if (allEdge[i] >= minEdge) {
235+
if (allEdge[i] >= l) {
236236
ans += allMaxv[i];
237237
}
238238
}
239+
return ans;
239240
}
240241

241-
public static void solve(int u) {
242-
calc(u);
242+
public static long solve(int u) {
243243
vis[u] = true;
244+
long ans = calc(u);
244245
for (int e = head[u]; e > 0; e = nxt[e]) {
245246
int v = to[e];
246247
if (!vis[v]) {
247248
total = siz[v];
248249
centroid = 0;
249250
// getCentroid1(v, 0);
250251
getCentroid2(v, 0);
251-
solve(centroid);
252+
ans += solve(centroid);
252253
}
253254
}
255+
return ans;
254256
}
255257

256258
public static void main(String[] args) throws Exception {
257259
FastReader in = new FastReader(System.in);
258260
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
259261
n = in.nextInt();
260-
minEdge = in.nextInt();
261-
maxEdge = in.nextInt();
262+
l = in.nextInt();
263+
r = in.nextInt();
262264
for (int i = 1, u, v, w; i < n; i++) {
263265
u = in.nextInt();
264266
v = in.nextInt();
@@ -270,7 +272,7 @@ public static void main(String[] args) throws Exception {
270272
centroid = 0;
271273
// getCentroid1(1, 0);
272274
getCentroid2(1, 0);
273-
solve(centroid);
275+
long ans = solve(centroid);
274276
out.println(ans << 1);
275277
out.flush();
276278
out.close();

src/class183/Code07_Maschera2.java

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package class183;
2+
3+
// 所有合法路径的魔力和,C++版
4+
// 一共有n个节点,给定n-1条边,每条边有边权,所有节点组成一棵树
5+
// 给定两个整数l、r,对于任意两个不同节点u、v,考虑它们之间的简单路径
6+
// 如果路径上边的数量在[l, r]范围内,则这条路径是合法路径
7+
// 路径的魔力值 = 路径上所有边权的最大值,打印所有合法路径的魔力和
8+
// 注意,u到v和v到u视为两条不同的路径,均要计入答案
9+
// 1 <= n、边权 <= 10^5
10+
// 测试链接 : https://www.luogu.com.cn/problem/P5351
11+
// 如下实现是C++的版本,C++版本和java版本逻辑完全一样
12+
// 提交如下代码,可以通过所有测试用例
13+
14+
//#include <bits/stdc++.h>
15+
//
16+
//using namespace std;
17+
//
18+
//struct Node {
19+
// int maxv, edge;
20+
//};
21+
//
22+
//bool NodeCmp(Node a, Node b) {
23+
// return a.maxv < b.maxv;
24+
//}
25+
//
26+
//const int MAXN = 100001;
27+
//int n, l, r;
28+
//
29+
//int head[MAXN];
30+
//int nxt[MAXN << 1];
31+
//int to[MAXN << 1];
32+
//int weight[MAXN << 1];
33+
//int cntg;
34+
//
35+
//bool vis[MAXN];
36+
//int siz[MAXN];
37+
//int maxPart[MAXN];
38+
//int total;
39+
//int centroid;
40+
//
41+
//Node cur[MAXN];
42+
//int cntc;
43+
//Node all[MAXN];
44+
//int cnta;
45+
//
46+
//int tree[MAXN];
47+
//
48+
//void addEdge(int u, int v, int w) {
49+
// nxt[++cntg] = head[u];
50+
// to[cntg] = v;
51+
// weight[cntg] = w;
52+
// head[u] = cntg;
53+
//}
54+
//
55+
//int lowbit(int i) {
56+
// return i & -i;
57+
//}
58+
//
59+
//void add(int i, int v) {
60+
// while (i <= r) {
61+
// tree[i] += v;
62+
// i += lowbit(i);
63+
// }
64+
//}
65+
//
66+
//int sum(int i) {
67+
// int ret = 0;
68+
// while (i > 0) {
69+
// ret += tree[i];
70+
// i -= lowbit(i);
71+
// }
72+
// return ret;
73+
//}
74+
//
75+
//void getCentroid(int u, int fa) {
76+
// siz[u] = 1;
77+
// maxPart[u] = 0;
78+
// for (int e = head[u]; e; e = nxt[e]) {
79+
// int v = to[e];
80+
// if (v != fa && !vis[v]) {
81+
// getCentroid(v, u);
82+
// siz[u] += siz[v];
83+
// maxPart[u] = max(maxPart[u], siz[v]);
84+
// }
85+
// }
86+
// maxPart[u] = max(maxPart[u], total - siz[u]);
87+
// if (centroid == 0 || maxPart[u] < maxPart[centroid]) {
88+
// centroid = u;
89+
// }
90+
//}
91+
//
92+
//void dfs(int u, int fa, int maxv, int edge) {
93+
// if (edge > r) {
94+
// return;
95+
// }
96+
// cur[++cntc] = { maxv, edge };
97+
// for (int e = head[u]; e; e = nxt[e]) {
98+
// int v = to[e];
99+
// if (v != fa && !vis[v]) {
100+
// dfs(v, u, max(maxv, weight[e]), edge + 1);
101+
// }
102+
// }
103+
//}
104+
//
105+
//long long calc(int u) {
106+
// long long ans = 0;
107+
// cnta = 0;
108+
// for (int e = head[u]; e; e = nxt[e]) {
109+
// int v = to[e];
110+
// if (!vis[v]) {
111+
// cntc = 0;
112+
// dfs(v, u, weight[e], 1);
113+
// sort(cur + 1, cur + cntc + 1, NodeCmp);
114+
// for (int i = 1; i <= cntc; i++) {
115+
// ans -= 1LL * cur[i].maxv * (sum(r - cur[i].edge) - sum(l - cur[i].edge - 1));
116+
// add(cur[i].edge, 1);
117+
// }
118+
// for (int i = 1; i <= cntc; i++) {
119+
// add(cur[i].edge, -1);
120+
// }
121+
// for (int i = 1; i <= cntc; i++) {
122+
// all[++cnta] = cur[i];
123+
// }
124+
// }
125+
// }
126+
// sort(all + 1, all + cnta + 1, NodeCmp);
127+
// for (int i = 1; i <= cnta; i++) {
128+
// ans += 1LL * all[i].maxv * (sum(r - all[i].edge) - sum(l - all[i].edge - 1));
129+
// add(all[i].edge, 1);
130+
// }
131+
// for (int i = 1; i <= cnta; i++) {
132+
// add(all[i].edge, -1);
133+
// }
134+
// for (int i = 1; i <= cnta; i++) {
135+
// if (all[i].edge >= l) {
136+
// ans += all[i].maxv;
137+
// }
138+
// }
139+
// return ans;
140+
//}
141+
//
142+
//long long solve(int u) {
143+
// vis[u] = true;
144+
// long long ans = calc(u);
145+
// for (int e = head[u]; e; e = nxt[e]) {
146+
// int v = to[e];
147+
// if (!vis[v]) {
148+
// total = siz[v];
149+
// centroid = 0;
150+
// getCentroid(v, 0);
151+
// ans += solve(centroid);
152+
// }
153+
// }
154+
// return ans;
155+
//}
156+
//
157+
//int main() {
158+
// ios::sync_with_stdio(false);
159+
// cin.tie(nullptr);
160+
// cin >> n >> l >> r;
161+
// for (int i = 1, u, v, w; i < n; i++) {
162+
// cin >> u >> v >> w;
163+
// addEdge(u, v, w);
164+
// addEdge(v, u, w);
165+
// }
166+
// total = n;
167+
// centroid = 0;
168+
// getCentroid(1, 0);
169+
// long long ans = solve(centroid);
170+
// cout << (ans << 1) << '\n';
171+
// return 0;
172+
//}

0 commit comments

Comments
 (0)