Skip to content

Commit 4b77ab3

Browse files
committed
第154场双周赛T1~T4 & 第445场周赛T1~T4 (8)
1 parent 06a9033 commit 4b77ab3

16 files changed

+710
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import java.util.Arrays;
2+
3+
public class Solution3512 {
4+
public int minOperations(int[] nums, int k) {
5+
int sum = Arrays.stream(nums).sum();
6+
return sum % k;
7+
}
8+
}
9+
/*
10+
3512. 使数组和能被 K 整除的最少操作次数
11+
https://leetcode.cn/problems/minimum-operations-to-make-array-sum-divisible-by-k/description/
12+
13+
第 154 场双周赛 T1。
14+
15+
给你一个整数数组 nums 和一个整数 k。你可以执行以下操作任意次:
16+
- 选择一个下标 i,并将 nums[i] 替换为 nums[i] - 1。
17+
返回使数组元素之和能被 k 整除所需的最小操作次数。
18+
提示:
19+
1 <= nums.length <= 1000
20+
1 <= nums[i] <= 1000
21+
1 <= k <= 100
22+
23+
数学,答案为 sum % k。
24+
时间复杂度 O(n)。
25+
*/
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
public class Solution3513 {
2+
public int uniqueXorTriplets(int[] nums) {
3+
int n = nums.length;
4+
if (n <= 2) return n;
5+
return 1 << bitsLen(n);
6+
}
7+
8+
// bits.Len:
9+
// Len returns the minimum number of bits required to represent x; the result is 0 for x == 0.
10+
private int bitsLen(long x) {
11+
if (x == 0) return 0;
12+
// return Long.toBinaryString(x).length();
13+
return Long.numberOfTrailingZeros(Long.highestOneBit(x)) + 1;
14+
}
15+
}
16+
/*
17+
3513. 不同 XOR 三元组的数目 I
18+
https://leetcode.cn/problems/number-of-unique-xor-triplets-i/description/
19+
20+
第 154 场双周赛 T2。
21+
22+
给你一个长度为 n 的整数数组 nums,其中 nums 是范围 [1, n] 内所有数的 排列 。
23+
XOR 三元组 定义为三个元素的异或值 nums[i] XOR nums[j] XOR nums[k],其中 i <= j <= k。
24+
返回所有可能三元组 (i, j, k) 中 不同 的 XOR 值的数量。
25+
排列 是一个集合中所有元素的重新排列。
26+
提示:
27+
1 <= n == nums.length <= 10^5
28+
1 <= nums[i] <= n
29+
nums 是从 1 到 n 的整数的一个排列。
30+
31+
构造题。
32+
时间复杂度 O(1)。
33+
*/
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
public class Solution3514 {
2+
// 253ms
3+
static class V1 {
4+
public int uniqueXorTriplets(int[] nums) {
5+
// int U = 1 << bitsLen(1500);
6+
final int U = 2048;
7+
8+
boolean[] has = new boolean[U];
9+
for (int i = 0; i < nums.length; i++) {
10+
for (int j = i; j < nums.length; j++) {
11+
has[nums[i] ^ nums[j]] = true;
12+
}
13+
}
14+
15+
boolean[] has3 = new boolean[U];
16+
for (int xy = 0; xy < U; xy++) {
17+
if (!has[xy]) {
18+
continue;
19+
}
20+
for (int z : nums) {
21+
has3[xy ^ z] = true;
22+
}
23+
}
24+
25+
int ans = 0;
26+
for (boolean b : has3) {
27+
if (b) ans++;
28+
}
29+
return ans;
30+
}
31+
}
32+
33+
// 50ms
34+
static class V2 {
35+
// 快速沃尔什变换 https://oi-wiki.org/math/poly/fwt/
36+
private void fwtXOR(long[] a, int rsh) {
37+
int n = a.length;
38+
for (int l = 2, k = 1; l <= n; l <<= 1, k <<= 1) {
39+
for (int i = 0; i < n; i += l) {
40+
for (int j = 0; j < k; j++) {
41+
long aij = a[i + j], aijk = a[i + j + k];
42+
a[i + j] = (aij + aijk) >> rsh;
43+
a[i + j + k] = (aij - aijk) >> rsh;
44+
}
45+
}
46+
}
47+
}
48+
49+
private long[] fwtXOR3(long[] a) {
50+
fwtXOR(a, 0);
51+
for (int i = 0; i < a.length; i++) {
52+
long x = a[i];
53+
a[i] *= x * x;
54+
}
55+
fwtXOR(a, 1);
56+
return a;
57+
}
58+
59+
public int uniqueXorTriplets(int[] nums) {
60+
// int U = 1 << bitsLen(1500);
61+
final int U = 2048;
62+
long[] cnt = new long[U];
63+
for (int x : nums) {
64+
cnt[x]++;
65+
}
66+
int ans = 0;
67+
for (long c : fwtXOR3(cnt)) {
68+
if (c > 0) ans++;
69+
}
70+
return ans;
71+
}
72+
}
73+
}
74+
/*
75+
3514. 不同 XOR 三元组的数目 II
76+
https://leetcode.cn/problems/number-of-unique-xor-triplets-ii/description/
77+
78+
第 154 场双周赛 T3。
79+
80+
给你一个整数数组 nums 。
81+
XOR 三元组 定义为三个元素的异或值 nums[i] XOR nums[j] XOR nums[k],其中 i <= j <= k。
82+
返回所有可能三元组 (i, j, k) 中 不同 的 XOR 值的数量。
83+
提示:
84+
1 <= nums.length <= 1500
85+
1 <= nums[i] <= 1500
86+
87+
循环优化,附 O(UlogU) FWT 做法
88+
https://leetcode.cn/problems/number-of-unique-xor-triplets-ii/solutions/3649377/mei-ju-fu-oulogu-fwt-zuo-fa-pythonjavacg-69r3/
89+
*/
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.List;
4+
5+
public class Solution3515 {
6+
private List<Integer>[] g;
7+
private int[] in, out, weight;
8+
private int clock;
9+
private BIT tr;
10+
11+
public int[] treeQueries(int n, int[][] edges, int[][] queries) {
12+
g = new ArrayList[n + 1];
13+
Arrays.setAll(g, e -> new ArrayList<>());
14+
for (int[] e : edges) {
15+
int x = e[0], y = e[1];
16+
g[x].add(y);
17+
g[y].add(x);
18+
}
19+
in = new int[n + 1];
20+
out = new int[n + 1];
21+
dfs(1, 0);
22+
23+
weight = new int[n + 1];
24+
tr = new BIT(n);
25+
for (int[] e : edges) {
26+
update(e[0], e[1], e[2]);
27+
}
28+
29+
List<Integer> ans = new ArrayList<>();
30+
for (int[] q : queries) {
31+
if (q[0] == 1) {
32+
update(q[1], q[2], q[3]);
33+
} else {
34+
ans.add(tr.query(in[q[1]]));
35+
}
36+
}
37+
return ans.stream().mapToInt(i -> i).toArray();
38+
}
39+
40+
private void dfs(int x, int fa) {
41+
in[x] = ++clock; // 进来的时间
42+
for (int y : g[x]) {
43+
if (y == fa) continue;
44+
dfs(y, x);
45+
}
46+
out[x] = clock; // 离开的时间
47+
}
48+
49+
private void update(int x, int y, int w) {
50+
// 保证 y 是 x 的儿子
51+
if (in[x] > in[y]) {
52+
y = x;
53+
}
54+
int d = w - weight[y]; // 边权的增量
55+
weight[y] = w;
56+
// 把子树 y 中的最短路长度都增加 d(用差分树状数组维护)
57+
tr.add(in[y], d);
58+
tr.add(out[y] + 1, -d);
59+
}
60+
61+
static class BIT {
62+
int n;
63+
int[] tree;
64+
65+
public BIT(int n) {
66+
this.n = n;
67+
tree = new int[n + 1];
68+
}
69+
70+
int lb(int x) {
71+
return x & -x;
72+
}
73+
74+
void add(int pos, int val) {
75+
for (; pos <= n; pos += lb(pos)) tree[pos] += val;
76+
}
77+
78+
int query(int pos) {
79+
int ret = 0;
80+
for (; pos > 0; pos -= lb(pos)) ret += tree[pos];
81+
return ret;
82+
}
83+
}
84+
}
85+
/*
86+
3515. 带权树中的最短路径
87+
https://leetcode.cn/problems/shortest-path-in-a-weighted-tree/description/
88+
89+
第 154 场双周赛 T4。
90+
91+
给你一个整数 n 和一个以节点 1 为根的无向带权树,该树包含 n 个编号从 1 到 n 的节点。它由一个长度为 n - 1 的二维数组 edges 表示,其中 edges[i] = [ui, vi, wi] 表示一条从节点 ui 到 vi 的无向边,权重为 wi。
92+
同时给你一个二维整数数组 queries,长度为 q,其中每个 queries[i] 为以下两种之一:
93+
- [1, u, v, w'] – 更新 节点 u 和 v 之间边的权重为 w',其中 (u, v) 保证是 edges 中存在的边。
94+
- [2, x] – 计算 从根节点 1 到节点 x 的 最短 路径距离。
95+
返回一个整数数组 answer,其中 answer[i] 是对于第 i 个 [2, x] 查询,从节点 1 到 x 的最短路径距离。
96+
提示:
97+
1 <= n <= 10^5
98+
edges.length == n - 1
99+
edges[i] == [ui, vi, wi]
100+
1 <= ui, vi <= n
101+
1 <= wi <= 10^4
102+
输入保证 edges 构成一棵合法的树。
103+
1 <= queries.length == q <= 10^5
104+
queries[i].length == 2 或 4
105+
- queries[i] == [1, u, v, w'],或者
106+
- queries[i] == [2, x]
107+
- 1 <= u, v, x <= n
108+
- (u, v) 一定是 edges 中的一条边。
109+
- 1 <= w' <= 10^4
110+
111+
DFS 时间戳 + 差分树状数组
112+
https://leetcode.cn/problems/shortest-path-in-a-weighted-tree/solutions/3649372/dfs-shi-jian-chuo-chai-fen-shu-zhuang-sh-h8q3/
113+
rating 2344 (clist.by)
114+
*/
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
public class Solution3516 {
2+
public int findClosest(int x, int y, int z) {
3+
int a = Math.abs(x - z);
4+
int b = Math.abs(y - z);
5+
if (a == b) return 0;
6+
return a < b ? 1 : 2;
7+
}
8+
}
9+
/*
10+
3516. 找到最近的人
11+
https://leetcode.cn/problems/find-closest-person/description/
12+
13+
第 445 场周赛 T1。
14+
15+
给你三个整数 x、y 和 z,表示数轴上三个人的位置:
16+
- x 是第 1 个人的位置。
17+
- y 是第 2 个人的位置。
18+
- z 是第 3 个人的位置,第 3 个人 不会移动 。
19+
第 1 个人和第 2 个人以 相同 的速度向第 3 个人移动。
20+
判断谁会 先 到达第 3 个人的位置:
21+
- 果第 1 个人先到达,返回 1 。
22+
- 果第 2 个人先到达,返回 2 。
23+
- 果两个人同时到达,返回 0 。
24+
根据上述规则返回结果。
25+
提示:
26+
1 <= x, y, z <= 100
27+
28+
中国时间 2025-04-13 周日 10:30
29+
广州·中肿。
30+
*/
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import java.util.Arrays;
2+
3+
public class Solution3517 {
4+
public String smallestPalindrome(String s) {
5+
int n = s.length();
6+
int m = n / 2;
7+
char[] t = s.substring(0, m).toCharArray();
8+
Arrays.sort(t);
9+
10+
StringBuilder ans = new StringBuilder();
11+
ans.append(t);
12+
if (n % 2 != 0) {
13+
ans.append(s.charAt(m));
14+
}
15+
ans.append(new StringBuilder(new String(t)).reverse());
16+
return ans.toString();
17+
}
18+
}
19+
/*
20+
3517. 最小回文排列 I
21+
https://leetcode.cn/problems/smallest-palindromic-rearrangement-i/description/
22+
23+
第 445 场周赛 T2。
24+
25+
给你一个 回文 字符串 s。
26+
返回 s 的按字典序排列的 最小 回文排列。
27+
如果一个字符串从前往后和从后往前读都相同,那么这个字符串是一个 回文 字符串。
28+
排列 是字符串中所有字符的重排。
29+
如果字符串 a 按字典序小于字符串 b,则表示在第一个不同的位置,a 中的字符比 b 中的对应字符在字母表中更靠前。
30+
如果在前 min(a.length, b.length) 个字符中没有区别,则较短的字符串按字典序更小。
31+
提示:
32+
1 <= s.length <= 10^5
33+
s 由小写英文字母组成。
34+
保证 s 是回文字符串。
35+
36+
排序左半部分
37+
*/

0 commit comments

Comments
 (0)