diff --git a/solution/3000-3099/3068.Find the Maximum Sum of Node Values/README.md b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/README.md index b527f4b4f3be4..8484e5d17c3b9 100644 --- a/solution/3000-3099/3068.Find the Maximum Sum of Node Values/README.md +++ b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/README.md @@ -98,7 +98,28 @@ tags: -### 方法一 +### 方法一:动态规划 + +对于任意一个数 $x$,与 $k$ 异或偶数次后,值不变。所以,对于一棵树的任意一条路径,我们将路径上所有的边都进行操作,那么该路径上除了起点和终点外,其他节点的值都不会改变。 + +另外,无论进行了多少次操作,总会有偶数个元素异或了 $k$,其余元素不变。 + +因此,问题转化为:对于数组 $\textit{nums}$,任选其中偶数个元素异或 $k$,使得和最大。 + +我们可以使用动态规划解决这个问题。设 $f_0$ 表示当前有偶数个元素异或了 $k$ 时的最大和,而 $f_1$ 表示当前有奇数个元素异或了 $k$ 时的最大和。那么状态转移方程为: + +$$ +\begin{aligned} +f_0 &= \max(f_0 + x, f_1 + (x \oplus k)) \\ +f_1 &= \max(f_1 + x, f_0 + (x \oplus k)) +\end{aligned} +$$ + +其中 $x$ 表示当前元素的值。 + +我们遍历数组 $\textit{nums}$,根据上述状态转移方程更新 $f_0$ 和 $f_1$,最后返回 $f_0$ 即可。 + +时间复杂度 $O(n)$,其中 $n$ 为数组 $\textit{nums}$ 的长度。空间复杂度 $O(1)$。 @@ -135,29 +156,13 @@ class Solution { class Solution { public: long long maximumValueSum(vector& nums, int k, vector>& edges) { - long long totalSum = 0; - int count = 0; - int positiveMin = INT_MAX; - int negativeMax = INT_MIN; - - for (int nodeValue : nums) { - int nodeValAfterOperation = nodeValue ^ k; - totalSum += nodeValue; - int netChange = nodeValAfterOperation - nodeValue; - - if (netChange > 0) { - positiveMin = min(positiveMin, netChange); - totalSum += netChange; - count += 1; - } else { - negativeMax = max(negativeMax, netChange); - } - } - - if (count % 2 == 0) { - return totalSum; + long long f0 = 0, f1 = -0x3f3f3f3f; + for (int x : nums) { + long long tmp = f0; + f0 = max(f0 + x, f1 + (x ^ k)); + f1 = max(f1 + x, tmp + (x ^ k)); } - return max(totalSum - positiveMin, totalSum + negativeMax); + return f0; } }; ``` @@ -165,7 +170,60 @@ public: #### Go ```go +func maximumValueSum(nums []int, k int, edges [][]int) int64 { + f0, f1 := 0, -0x3f3f3f3f + for _, x := range nums { + f0, f1 = max(f0+x, f1+(x^k)), max(f1+x, f0+(x^k)) + } + return int64(f0) +} +``` + +#### TypeScript + +```ts +function maximumValueSum(nums: number[], k: number, edges: number[][]): number { + let [f0, f1] = [0, -Infinity]; + for (const x of nums) { + [f0, f1] = [Math.max(f0 + x, f1 + (x ^ k)), Math.max(f1 + x, f0 + (x ^ k))]; + } + return f0; +} +``` + +#### Rust +```rust +impl Solution { + pub fn maximum_value_sum(nums: Vec, k: i32, edges: Vec>) -> i64 { + let mut f0: i64 = 0; + let mut f1: i64 = i64::MIN; + + for &x in &nums { + let tmp = f0; + f0 = std::cmp::max(f0 + x as i64, f1 + (x ^ k) as i64); + f1 = std::cmp::max(f1 + x as i64, tmp + (x ^ k) as i64); + } + + f0 + } +} +``` + +#### C# + +```cs +public class Solution { + public long MaximumValueSum(int[] nums, int k, int[][] edges) { + long f0 = 0, f1 = -0x3f3f3f3f; + foreach (int x in nums) { + long tmp = f0; + f0 = Math.Max(f0 + x, f1 + (x ^ k)); + f1 = Math.Max(f1 + x, tmp + (x ^ k)); + } + return f0; + } +} ``` diff --git a/solution/3000-3099/3068.Find the Maximum Sum of Node Values/README_EN.md b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/README_EN.md index de45a57904708..b31fcfbf22a67 100644 --- a/solution/3000-3099/3068.Find the Maximum Sum of Node Values/README_EN.md +++ b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/README_EN.md @@ -90,7 +90,28 @@ It can be shown that 9 is the maximum achievable sum of values. -### Solution 1 +### Solution 1: Dynamic Programming + +For any number $x$, its value remains unchanged after being XORed with $k$ an even number of times. Therefore, for any path in a tree, if we perform the operation on all edges in the path, the values of all nodes on the path except the start and end nodes will not change. + +Additionally, no matter how many operations are performed, there will always be an even number of elements XORed with $k$, and the remaining elements will remain unchanged. + +Thus, the problem is transformed into: for the array $\textit{nums}$, select an even number of elements to XOR with $k$ to maximize the sum. + +We can use dynamic programming to solve this problem. Let $f_0$ represent the maximum sum when an even number of elements have been XORed with $k$, and $f_1$ represent the maximum sum when an odd number of elements have been XORed with $k$. The state transition equations are: + +$$ +\begin{aligned} +f_0 &= \max(f_0 + x, f_1 + (x \oplus k)) \\ +f_1 &= \max(f_1 + x, f_0 + (x \oplus k)) +\end{aligned} +$$ + +where $x$ represents the current element's value. + +We traverse the array $\textit{nums}$ and update $f_0$ and $f_1$ according to the above state transition equations. Finally, we return $f_0$. + +The time complexity is $O(n)$, where $n$ is the length of the array $\textit{nums}$. The space complexity is $O(1)$. @@ -100,8 +121,8 @@ It can be shown that 9 is the maximum achievable sum of values. class Solution: def maximumValueSum(self, nums: List[int], k: int, edges: List[List[int]]) -> int: f0, f1 = 0, -inf - for v in nums: - f0, f1 = max(f0 + v, f1 + (v ^ k)), max(f1 + v, f0 + (v ^ k)) + for x in nums: + f0, f1 = max(f0 + x, f1 + (x ^ k)), max(f1 + x, f0 + (x ^ k)) return f0 ``` @@ -127,29 +148,13 @@ class Solution { class Solution { public: long long maximumValueSum(vector& nums, int k, vector>& edges) { - long long totalSum = 0; - int count = 0; - int positiveMin = INT_MAX; - int negativeMax = INT_MIN; - - for (int nodeValue : nums) { - int nodeValAfterOperation = nodeValue ^ k; - totalSum += nodeValue; - int netChange = nodeValAfterOperation - nodeValue; - - if (netChange > 0) { - positiveMin = min(positiveMin, netChange); - totalSum += netChange; - count += 1; - } else { - negativeMax = max(negativeMax, netChange); - } - } - - if (count % 2 == 0) { - return totalSum; + long long f0 = 0, f1 = -0x3f3f3f3f; + for (int x : nums) { + long long tmp = f0; + f0 = max(f0 + x, f1 + (x ^ k)); + f1 = max(f1 + x, tmp + (x ^ k)); } - return max(totalSum - positiveMin, totalSum + negativeMax); + return f0; } }; ``` @@ -157,7 +162,60 @@ public: #### Go ```go +func maximumValueSum(nums []int, k int, edges [][]int) int64 { + f0, f1 := 0, -0x3f3f3f3f + for _, x := range nums { + f0, f1 = max(f0+x, f1+(x^k)), max(f1+x, f0+(x^k)) + } + return int64(f0) +} +``` + +#### TypeScript + +```ts +function maximumValueSum(nums: number[], k: number, edges: number[][]): number { + let [f0, f1] = [0, -Infinity]; + for (const x of nums) { + [f0, f1] = [Math.max(f0 + x, f1 + (x ^ k)), Math.max(f1 + x, f0 + (x ^ k))]; + } + return f0; +} +``` + +#### Rust +```rust +impl Solution { + pub fn maximum_value_sum(nums: Vec, k: i32, edges: Vec>) -> i64 { + let mut f0: i64 = 0; + let mut f1: i64 = i64::MIN; + + for &x in &nums { + let tmp = f0; + f0 = std::cmp::max(f0 + x as i64, f1 + (x ^ k) as i64); + f1 = std::cmp::max(f1 + x as i64, tmp + (x ^ k) as i64); + } + + f0 + } +} +``` + +#### C# + +```cs +public class Solution { + public long MaximumValueSum(int[] nums, int k, int[][] edges) { + long f0 = 0, f1 = -0x3f3f3f3f; + foreach (int x in nums) { + long tmp = f0; + f0 = Math.Max(f0 + x, f1 + (x ^ k)); + f1 = Math.Max(f1 + x, tmp + (x ^ k)); + } + return f0; + } +} ``` diff --git a/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.cpp b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.cpp index 76da2b6d44889..c52e439a6bd66 100644 --- a/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.cpp +++ b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.cpp @@ -1,28 +1,12 @@ class Solution { public: long long maximumValueSum(vector& nums, int k, vector>& edges) { - long long totalSum = 0; - int count = 0; - int positiveMin = INT_MAX; - int negativeMax = INT_MIN; - - for (int nodeValue : nums) { - int nodeValAfterOperation = nodeValue ^ k; - totalSum += nodeValue; - int netChange = nodeValAfterOperation - nodeValue; - - if (netChange > 0) { - positiveMin = min(positiveMin, netChange); - totalSum += netChange; - count += 1; - } else { - negativeMax = max(negativeMax, netChange); - } + long long f0 = 0, f1 = -0x3f3f3f3f; + for (int x : nums) { + long long tmp = f0; + f0 = max(f0 + x, f1 + (x ^ k)); + f1 = max(f1 + x, tmp + (x ^ k)); } - - if (count % 2 == 0) { - return totalSum; - } - return max(totalSum - positiveMin, totalSum + negativeMax); + return f0; } }; diff --git a/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.cs b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.cs new file mode 100644 index 0000000000000..03fbb853e08ed --- /dev/null +++ b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.cs @@ -0,0 +1,11 @@ +public class Solution { + public long MaximumValueSum(int[] nums, int k, int[][] edges) { + long f0 = 0, f1 = -0x3f3f3f3f; + foreach (int x in nums) { + long tmp = f0; + f0 = Math.Max(f0 + x, f1 + (x ^ k)); + f1 = Math.Max(f1 + x, tmp + (x ^ k)); + } + return f0; + } +} diff --git a/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.go b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.go new file mode 100644 index 0000000000000..097c05f9dc1e3 --- /dev/null +++ b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.go @@ -0,0 +1,7 @@ +func maximumValueSum(nums []int, k int, edges [][]int) int64 { + f0, f1 := 0, -0x3f3f3f3f + for _, x := range nums { + f0, f1 = max(f0+x, f1+(x^k)), max(f1+x, f0+(x^k)) + } + return int64(f0) +} diff --git a/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.rs b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.rs new file mode 100644 index 0000000000000..b8789ed106427 --- /dev/null +++ b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.rs @@ -0,0 +1,14 @@ +impl Solution { + pub fn maximum_value_sum(nums: Vec, k: i32, edges: Vec>) -> i64 { + let mut f0: i64 = 0; + let mut f1: i64 = i64::MIN; + + for &x in &nums { + let tmp = f0; + f0 = std::cmp::max(f0 + x as i64, f1 + (x ^ k) as i64); + f1 = std::cmp::max(f1 + x as i64, tmp + (x ^ k) as i64); + } + + f0 + } +} diff --git a/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.ts b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.ts new file mode 100644 index 0000000000000..2769ab13f6ec0 --- /dev/null +++ b/solution/3000-3099/3068.Find the Maximum Sum of Node Values/Solution.ts @@ -0,0 +1,7 @@ +function maximumValueSum(nums: number[], k: number, edges: number[][]): number { + let [f0, f1] = [0, -Infinity]; + for (const x of nums) { + [f0, f1] = [Math.max(f0 + x, f1 + (x ^ k)), Math.max(f1 + x, f0 + (x ^ k))]; + } + return f0; +}