diff --git a/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/Solution.java b/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/Solution.java
new file mode 100644
index 000000000..56842a60f
--- /dev/null
+++ b/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/Solution.java
@@ -0,0 +1,45 @@
+package g3501_3600.s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues;
+
+// #Medium #Array #Hash_Table #Sorting #Greedy #Heap_Priority_Queue
+// #2025_06_10_Time_2_ms_(100.00%)_Space_64.25_MB_(40.62%)
+
+public class Solution {
+ public int maxSumDistinctTriplet(int[] x, int[] y) {
+ int index = -1;
+ int max = -1;
+ int sum = 0;
+ for (int i = 0; i < y.length; i++) {
+ if (y[i] > max) {
+ max = y[i];
+ index = i;
+ }
+ }
+ sum += max;
+ if (max == -1) {
+ return -1;
+ }
+ int index2 = -1;
+ max = -1;
+ for (int i = 0; i < y.length; i++) {
+ if (y[i] > max && x[i] != x[index]) {
+ max = y[i];
+ index2 = i;
+ }
+ }
+ sum += max;
+ if (max == -1) {
+ return -1;
+ }
+ max = -1;
+ for (int i = 0; i < y.length; i++) {
+ if (y[i] > max && x[i] != x[index] && x[i] != x[index2]) {
+ max = y[i];
+ }
+ }
+ if (max == -1) {
+ return -1;
+ }
+ sum += max;
+ return sum;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/readme.md b/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/readme.md
new file mode 100644
index 000000000..3c88dbe58
--- /dev/null
+++ b/src/main/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/readme.md
@@ -0,0 +1,40 @@
+3572\. Maximize Y‑Sum by Picking a Triplet of Distinct X‑Values
+
+Medium
+
+You are given two integer arrays `x` and `y`, each of length `n`. You must choose three **distinct** indices `i`, `j`, and `k` such that:
+
+* `x[i] != x[j]`
+* `x[j] != x[k]`
+* `x[k] != x[i]`
+
+Your goal is to **maximize** the value of `y[i] + y[j] + y[k]` under these conditions. Return the **maximum** possible sum that can be obtained by choosing such a triplet of indices.
+
+If no such triplet exists, return -1.
+
+**Example 1:**
+
+**Input:** x = [1,2,1,3,2], y = [5,3,4,6,2]
+
+**Output:** 14
+
+**Explanation:**
+
+* Choose `i = 0` (`x[i] = 1`, `y[i] = 5`), `j = 1` (`x[j] = 2`, `y[j] = 3`), `k = 3` (`x[k] = 3`, `y[k] = 6`).
+* All three values chosen from `x` are distinct. `5 + 3 + 6 = 14` is the maximum we can obtain. Hence, the output is 14.
+
+**Example 2:**
+
+**Input:** x = [1,2,1,2], y = [4,5,6,7]
+
+**Output:** \-1
+
+**Explanation:**
+
+* There are only two distinct values in `x`. Hence, the output is -1.
+
+**Constraints:**
+
+* `n == x.length == y.length`
+* 3 <= n <= 105
+* 1 <= x[i], y[i] <= 106
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/Solution.java b/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/Solution.java
new file mode 100644
index 000000000..36cbfa748
--- /dev/null
+++ b/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/Solution.java
@@ -0,0 +1,28 @@
+package g3501_3600.s3573_best_time_to_buy_and_sell_stock_v;
+
+// #Medium #Array #Dynamic_Programming #2025_06_10_Time_10_ms_(99.46%)_Space_44.46_MB_(97.36%)
+
+public class Solution {
+ public long maximumProfit(int[] prices, int k) {
+ int n = prices.length;
+ long[] prev = new long[n];
+ long[] curr = new long[n];
+ for (int t = 1; t <= k; t++) {
+ long bestLong = -prices[0];
+ long bestShort = prices[0];
+ curr[0] = 0;
+ for (int i = 1; i < n; i++) {
+ long res = curr[i - 1];
+ res = Math.max(res, prices[i] + bestLong);
+ res = Math.max(res, -prices[i] + bestShort);
+ curr[i] = res;
+ bestLong = Math.max(bestLong, prev[i - 1] - prices[i]);
+ bestShort = Math.max(bestShort, prev[i - 1] + prices[i]);
+ }
+ long[] tmp = prev;
+ prev = curr;
+ curr = tmp;
+ }
+ return prev[n - 1];
+ }
+}
diff --git a/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/readme.md b/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/readme.md
new file mode 100644
index 000000000..89e19ab66
--- /dev/null
+++ b/src/main/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/readme.md
@@ -0,0 +1,49 @@
+3573\. Best Time to Buy and Sell Stock V
+
+Medium
+
+You are given an integer array `prices` where `prices[i]` is the price of a stock in dollars on the ith
day, and an integer `k`.
+
+You are allowed to make at most `k` transactions, where each transaction can be either of the following:
+
+* **Normal transaction**: Buy on day `i`, then sell on a later day `j` where `i < j`. You profit `prices[j] - prices[i]`.
+
+* **Short selling transaction**: Sell on day `i`, then buy back on a later day `j` where `i < j`. You profit `prices[i] - prices[j]`.
+
+
+**Note** that you must complete each transaction before starting another. Additionally, you can't buy or sell on the same day you are selling or buying back as part of a previous transaction.
+
+Return the **maximum** total profit you can earn by making **at most** `k` transactions.
+
+**Example 1:**
+
+**Input:** prices = [1,7,9,8,2], k = 2
+
+**Output:** 14
+
+**Explanation:**
+
+We can make $14 of profit through 2 transactions:
+
+* A normal transaction: buy the stock on day 0 for $1 then sell it on day 2 for $9.
+* A short selling transaction: sell the stock on day 3 for $8 then buy back on day 4 for $2.
+
+**Example 2:**
+
+**Input:** prices = [12,16,19,19,8,1,19,13,9], k = 3
+
+**Output:** 36
+
+**Explanation:**
+
+We can make $36 of profit through 3 transactions:
+
+* A normal transaction: buy the stock on day 0 for $12 then sell it on day 2 for $19.
+* A short selling transaction: sell the stock on day 3 for $19 then buy back on day 4 for $8.
+* A normal transaction: buy the stock on day 5 for $1 then sell it on day 6 for $19.
+
+**Constraints:**
+
+* 2 <= prices.length <= 103
+* 1 <= prices[i] <= 109
+* `1 <= k <= prices.length / 2`
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/Solution.java b/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/Solution.java
new file mode 100644
index 000000000..4e95f3971
--- /dev/null
+++ b/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/Solution.java
@@ -0,0 +1,69 @@
+package g3501_3600.s3574_maximize_subarray_gcd_score;
+
+// #Hard #Array #Math #Enumeration #Number_Theory
+// #2025_06_10_Time_13_ms_(100.00%)_Space_45.07_MB_(78.08%)
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@SuppressWarnings("unchecked")
+public class Solution {
+ public long maxGCDScore(int[] nums, int k) {
+ int mx = 0;
+ for (int x : nums) {
+ mx = Math.max(mx, x);
+ }
+ int width = 32 - Integer.numberOfLeadingZeros(mx);
+ List[] lowbitPos = new List[width];
+ Arrays.setAll(lowbitPos, i -> new ArrayList<>());
+ int[][] intervals = new int[width + 1][3];
+ int size = 0;
+ long ans = 0;
+ for (int i = 0; i < nums.length; i++) {
+ int x = nums[i];
+ int tz = Integer.numberOfTrailingZeros(x);
+ lowbitPos[tz].add(i);
+ for (int j = 0; j < size; j++) {
+ intervals[j][0] = gcd(intervals[j][0], x);
+ }
+ intervals[size][0] = x;
+ intervals[size][1] = i - 1;
+ intervals[size][2] = i;
+ size++;
+ int idx = 1;
+ for (int j = 1; j < size; j++) {
+ if (intervals[j][0] != intervals[j - 1][0]) {
+ intervals[idx][0] = intervals[j][0];
+ intervals[idx][1] = intervals[j][1];
+ intervals[idx][2] = intervals[j][2];
+ idx++;
+ } else {
+ intervals[idx - 1][2] = intervals[j][2];
+ }
+ }
+ size = idx;
+ for (int j = 0; j < size; j++) {
+ int g = intervals[j][0];
+ int l = intervals[j][1];
+ int r = intervals[j][2];
+ ans = Math.max(ans, (long) g * (i - l));
+ List pos = lowbitPos[Integer.numberOfTrailingZeros(g)];
+ int minL = pos.size() > k ? Math.max(l, pos.get(pos.size() - k - 1)) : l;
+ if (minL < r) {
+ ans = Math.max(ans, (long) g * 2 * (i - minL));
+ }
+ }
+ }
+ return ans;
+ }
+
+ private int gcd(int a, int b) {
+ while (a != 0) {
+ int tmp = a;
+ a = b % a;
+ b = tmp;
+ }
+ return b;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/readme.md b/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/readme.md
new file mode 100644
index 000000000..09b9789ec
--- /dev/null
+++ b/src/main/java/g3501_3600/s3574_maximize_subarray_gcd_score/readme.md
@@ -0,0 +1,56 @@
+3574\. Maximize Subarray GCD Score
+
+Hard
+
+You are given an array of positive integers `nums` and an integer `k`.
+
+You may perform at most `k` operations. In each operation, you can choose one element in the array and **double** its value. Each element can be doubled **at most** once.
+
+The **score** of a contiguous **subarray** is defined as the **product** of its length and the _greatest common divisor (GCD)_ of all its elements.
+
+Your task is to return the **maximum** **score** that can be achieved by selecting a contiguous subarray from the modified array.
+
+**Note:**
+
+* The **greatest common divisor (GCD)** of an array is the largest integer that evenly divides all the array elements.
+
+**Example 1:**
+
+**Input:** nums = [2,4], k = 1
+
+**Output:** 8
+
+**Explanation:**
+
+* Double `nums[0]` to 4 using one operation. The modified array becomes `[4, 4]`.
+* The GCD of the subarray `[4, 4]` is 4, and the length is 2.
+* Thus, the maximum possible score is `2 × 4 = 8`.
+
+**Example 2:**
+
+**Input:** nums = [3,5,7], k = 2
+
+**Output:** 14
+
+**Explanation:**
+
+* Double `nums[2]` to 14 using one operation. The modified array becomes `[3, 5, 14]`.
+* The GCD of the subarray `[14]` is 14, and the length is 1.
+* Thus, the maximum possible score is `1 × 14 = 14`.
+
+**Example 3:**
+
+**Input:** nums = [5,5,5], k = 1
+
+**Output:** 15
+
+**Explanation:**
+
+* The subarray `[5, 5, 5]` has a GCD of 5, and its length is 3.
+* Since doubling any element doesn't improve the score, the maximum score is `3 × 5 = 15`.
+
+**Constraints:**
+
+* `1 <= n == nums.length <= 1500`
+* 1 <= nums[i] <= 109
+* `1 <= k <= n`
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/Solution.java b/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/Solution.java
new file mode 100644
index 000000000..0d51fce52
--- /dev/null
+++ b/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/Solution.java
@@ -0,0 +1,85 @@
+package g3501_3600.s3575_maximum_good_subtree_score;
+
+// #Hard #Array #Dynamic_Programming #Depth_First_Search #Tree #Bit_Manipulation #Bitmask
+// #2025_06_10_Time_92_ms_(98.73%)_Space_55.23_MB_(11.71%)
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@SuppressWarnings("unchecked")
+public class Solution {
+ private int digits = 10;
+ private int full = 1 << digits;
+ private long neg = Long.MIN_VALUE / 4;
+ private long mod = (long) 1e9 + 7;
+ private List[] tree;
+ private int[] val;
+ private int[] mask;
+ private boolean[] isOk;
+ private long res = 0;
+
+ public int goodSubtreeSum(int[] vals, int[] par) {
+ int n = vals.length;
+ val = vals;
+ mask = new int[n];
+ isOk = new boolean[n];
+ for (int i = 0; i < n; i++) {
+ int m = 0;
+ int v = vals[i];
+ boolean valid = true;
+ while (v > 0) {
+ int d = v % 10;
+ if (((m >> d) & 1) == 1) {
+ valid = false;
+ break;
+ }
+ m |= 1 << d;
+ v /= 10;
+ }
+ mask[i] = m;
+ isOk[i] = valid;
+ }
+ tree = new ArrayList[n];
+ Arrays.setAll(tree, ArrayList::new);
+ int root = 0;
+ for (int i = 1; i < n; i++) {
+ tree[par[i]].add(i);
+ }
+ dfs(root);
+ return (int) (res % mod);
+ }
+
+ private long[] dfs(int u) {
+ long[] dp = new long[full];
+ Arrays.fill(dp, neg);
+ dp[0] = 0;
+ if (isOk[u]) {
+ dp[mask[u]] = val[u];
+ }
+ for (int v : tree[u]) {
+ long[] child = dfs(v);
+ long[] newDp = Arrays.copyOf(dp, full);
+ for (int m1 = 0; m1 < full; m1++) {
+ if (dp[m1] < 0) {
+ continue;
+ }
+ int remain = full - 1 - m1;
+ for (int m2 = remain; m2 > 0; m2 = (m2 - 1) & remain) {
+ if (child[m2] < 0) {
+ continue;
+ }
+ int newM = m1 | m2;
+ newDp[newM] = Math.max(newDp[newM], dp[m1] + child[m2]);
+ }
+ }
+ dp = newDp;
+ }
+ long best = 0;
+ for (long v : dp) {
+ best = Math.max(best, v);
+ }
+ res = (res + best) % mod;
+ return dp;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/readme.md b/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/readme.md
new file mode 100644
index 000000000..bb1a07b9c
--- /dev/null
+++ b/src/main/java/g3501_3600/s3575_maximum_good_subtree_score/readme.md
@@ -0,0 +1,81 @@
+3575\. Maximum Good Subtree Score
+
+Hard
+
+You are given an undirected tree rooted at node 0 with `n` nodes numbered from 0 to `n - 1`. Each node `i` has an integer value `vals[i]`, and its parent is given by `par[i]`.
+
+A **subset** of nodes within the **subtree** of a node is called **good** if every digit from 0 to 9 appears **at most** once in the decimal representation of the values of the selected nodes.
+
+The **score** of a good subset is the sum of the values of its nodes.
+
+Define an array `maxScore` of length `n`, where `maxScore[u]` represents the **maximum** possible sum of values of a good subset of nodes that belong to the subtree rooted at node `u`, including `u` itself and all its descendants.
+
+Return the sum of all values in `maxScore`.
+
+Since the answer may be large, return it **modulo** 109 + 7
.
+
+**Example 1:**
+
+**Input:** vals = [2,3], par = [-1,0]
+
+**Output:** 8
+
+**Explanation:**
+
+
+
+* The subtree rooted at node 0 includes nodes `{0, 1}`. The subset `{2, 3}` is good as the digits 2 and 3 appear only once. The score of this subset is `2 + 3 = 5`.
+* The subtree rooted at node 1 includes only node `{1}`. The subset `{3}` is good. The score of this subset is 3.
+* The `maxScore` array is `[5, 3]`, and the sum of all values in `maxScore` is `5 + 3 = 8`. Thus, the answer is 8.
+
+**Example 2:**
+
+**Input:** vals = [1,5,2], par = [-1,0,0]
+
+**Output:** 15
+
+**Explanation:**
+
+****
+
+* The subtree rooted at node 0 includes nodes `{0, 1, 2}`. The subset `{1, 5, 2}` is good as the digits 1, 5 and 2 appear only once. The score of this subset is `1 + 5 + 2 = 8`.
+* The subtree rooted at node 1 includes only node `{1}`. The subset `{5}` is good. The score of this subset is 5.
+* The subtree rooted at node 2 includes only node `{2}`. The subset `{2}` is good. The score of this subset is 2.
+* The `maxScore` array is `[8, 5, 2]`, and the sum of all values in `maxScore` is `8 + 5 + 2 = 15`. Thus, the answer is 15.
+
+**Example 3:**
+
+**Input:** vals = [34,1,2], par = [-1,0,1]
+
+**Output:** 42
+
+**Explanation:**
+
+
+
+* The subtree rooted at node 0 includes nodes `{0, 1, 2}`. The subset `{34, 1, 2}` is good as the digits 3, 4, 1 and 2 appear only once. The score of this subset is `34 + 1 + 2 = 37`.
+* The subtree rooted at node 1 includes node `{1, 2}`. The subset `{1, 2}` is good as the digits 1 and 2 appear only once. The score of this subset is `1 + 2 = 3`.
+* The subtree rooted at node 2 includes only node `{2}`. The subset `{2}` is good. The score of this subset is 2.
+* The `maxScore` array is `[37, 3, 2]`, and the sum of all values in `maxScore` is `37 + 3 + 2 = 42`. Thus, the answer is 42.
+
+**Example 4:**
+
+**Input:** vals = [3,22,5], par = [-1,0,1]
+
+**Output:** 18
+
+**Explanation:**
+
+* The subtree rooted at node 0 includes nodes `{0, 1, 2}`. The subset `{3, 22, 5}` is not good, as digit 2 appears twice. Therefore, the subset `{3, 5}` is valid. The score of this subset is `3 + 5 = 8`.
+* The subtree rooted at node 1 includes nodes `{1, 2}`. The subset `{22, 5}` is not good, as digit 2 appears twice. Therefore, the subset `{5}` is valid. The score of this subset is 5.
+* The subtree rooted at node 2 includes `{2}`. The subset `{5}` is good. The score of this subset is 5.
+* The `maxScore` array is `[8, 5, 5]`, and the sum of all values in `maxScore` is `8 + 5 + 5 = 18`. Thus, the answer is 18.
+
+**Constraints:**
+
+* `1 <= n == vals.length <= 500`
+* 1 <= vals[i] <= 109
+* `par.length == n`
+* `par[0] == -1`
+* `0 <= par[i] < n` for `i` in `[1, n - 1]`
+* The input is generated such that the parent array `par` represents a valid tree.
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/Solution.java b/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/Solution.java
new file mode 100644
index 000000000..4c1a7dcee
--- /dev/null
+++ b/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/Solution.java
@@ -0,0 +1,44 @@
+package g3501_3600.s3576_transform_array_to_all_equal_elements;
+
+// #Medium #Array #Greedy #2025_06_10_Time_7_ms_(99.81%)_Space_56.56_MB_(99.57%)
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Solution {
+ public boolean canMakeEqual(int[] nums, int k) {
+ int n = nums.length;
+ if (n == 1) {
+ return true;
+ }
+ int prod = 1;
+ for (int x : nums) {
+ prod *= x;
+ }
+ List targets = new ArrayList<>();
+ for (int target : new int[] {1, -1}) {
+ int tPowN = (n % 2 == 0 ? 1 : target);
+ if (tPowN == prod) {
+ targets.add(target);
+ }
+ }
+ if (targets.isEmpty()) {
+ return false;
+ }
+ for (int target : targets) {
+ int ops = 0;
+ int[] a = nums.clone();
+ for (int i = 0; i < n - 1 && ops <= k; i++) {
+ if (a[i] != target) {
+ a[i] = -a[i];
+ a[i + 1] = -a[i + 1];
+ ops++;
+ }
+ }
+ if (ops <= k && a[n - 1] == target) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/readme.md b/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/readme.md
new file mode 100644
index 000000000..61c7d3948
--- /dev/null
+++ b/src/main/java/g3501_3600/s3576_transform_array_to_all_equal_elements/readme.md
@@ -0,0 +1,43 @@
+3576\. Transform Array to All Equal Elements
+
+Medium
+
+You are given an integer array `nums` of size `n` containing only `1` and `-1`, and an integer `k`.
+
+You can perform the following operation at most `k` times:
+
+* Choose an index `i` (`0 <= i < n - 1`), and **multiply** both `nums[i]` and `nums[i + 1]` by `-1`.
+
+
+**Note** that you can choose the same index `i` more than once in **different** operations.
+
+Return `true` if it is possible to make all elements of the array **equal** after at most `k` operations, and `false` otherwise.
+
+**Example 1:**
+
+**Input:** nums = [1,-1,1,-1,1], k = 3
+
+**Output:** true
+
+**Explanation:**
+
+We can make all elements in the array equal in 2 operations as follows:
+
+* Choose index `i = 1`, and multiply both `nums[1]` and `nums[2]` by -1. Now `nums = [1,1,-1,-1,1]`.
+* Choose index `i = 2`, and multiply both `nums[2]` and `nums[3]` by -1. Now `nums = [1,1,1,1,1]`.
+
+**Example 2:**
+
+**Input:** nums = [-1,-1,-1,1,1,1], k = 5
+
+**Output:** false
+
+**Explanation:**
+
+It is not possible to make all array elements equal in at most 5 operations.
+
+**Constraints:**
+
+* 1 <= n == nums.length <= 105
+* `nums[i]` is either -1 or 1.
+* `1 <= k <= n`
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/Solution.java b/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/Solution.java
new file mode 100644
index 000000000..6a5944a5a
--- /dev/null
+++ b/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/Solution.java
@@ -0,0 +1,22 @@
+package g3501_3600.s3577_count_the_number_of_computer_unlocking_permutations;
+
+// #Medium #Array #Math #Combinatorics #Brainteaser
+// #2025_06_10_Time_1_ms_(100.00%)_Space_62.24_MB_(22.08%)
+
+public class Solution {
+ private static final int MOD = 1_000_000_007;
+
+ public int countPermutations(int[] complexity) {
+ int n = complexity.length;
+ for (int i = 1; i < n; i++) {
+ if (complexity[i] <= complexity[0]) {
+ return 0;
+ }
+ }
+ long ans = 1;
+ for (int x = 2; x < n; x++) {
+ ans = (ans * x) % MOD;
+ }
+ return (int) ans;
+ }
+}
diff --git a/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/readme.md b/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/readme.md
new file mode 100644
index 000000000..8bc0a14cc
--- /dev/null
+++ b/src/main/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/readme.md
@@ -0,0 +1,52 @@
+3577\. Count the Number of Computer Unlocking Permutations
+
+Medium
+
+You are given an array `complexity` of length `n`.
+
+There are `n` **locked** computers in a room with labels from 0 to `n - 1`, each with its own **unique** password. The password of the computer `i` has a complexity `complexity[i]`.
+
+The password for the computer labeled 0 is **already** decrypted and serves as the root. All other computers must be unlocked using it or another previously unlocked computer, following this information:
+
+* You can decrypt the password for the computer `i` using the password for computer `j`, where `j` is **any** integer less than `i` with a lower complexity. (i.e. `j < i` and `complexity[j] < complexity[i]`)
+* To decrypt the password for computer `i`, you must have already unlocked a computer `j` such that `j < i` and `complexity[j] < complexity[i]`.
+
+Find the number of permutations of `[0, 1, 2, ..., (n - 1)]` that represent a valid order in which the computers can be unlocked, starting from computer 0 as the only initially unlocked one.
+
+Since the answer may be large, return it **modulo** 109 + 7.
+
+**Note** that the password for the computer **with label** 0 is decrypted, and _not_ the computer with the first position in the permutation.
+
+**Example 1:**
+
+**Input:** complexity = [1,2,3]
+
+**Output:** 2
+
+**Explanation:**
+
+The valid permutations are:
+
+* [0, 1, 2]
+ * Unlock computer 0 first with root password.
+ * Unlock computer 1 with password of computer 0 since `complexity[0] < complexity[1]`.
+ * Unlock computer 2 with password of computer 1 since `complexity[1] < complexity[2]`.
+* [0, 2, 1]
+ * Unlock computer 0 first with root password.
+ * Unlock computer 2 with password of computer 0 since `complexity[0] < complexity[2]`.
+ * Unlock computer 1 with password of computer 0 since `complexity[0] < complexity[1]`.
+
+**Example 2:**
+
+**Input:** complexity = [3,3,3,4,4,4]
+
+**Output:** 0
+
+**Explanation:**
+
+There are no possible permutations which can unlock all computers.
+
+**Constraints:**
+
+* 2 <= complexity.length <= 105
+* 1 <= complexity[i] <= 109
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/Solution.java b/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/Solution.java
new file mode 100644
index 000000000..bec158796
--- /dev/null
+++ b/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/Solution.java
@@ -0,0 +1,49 @@
+package g3501_3600.s3578_count_partitions_with_max_min_difference_at_most_k;
+
+// #Medium #Array #Dynamic_Programming #Prefix_Sum #Sliding_Window #Queue #Monotonic_Queue
+// #2025_06_10_Time_16_ms_(99.88%)_Space_55.12_MB_(98.72%)
+
+public class Solution {
+ private static final int MOD = 1_000_000_007;
+
+ public int countPartitions(int[] nums, int k) {
+ int n = nums.length;
+ int[] dp = new int[n + 1];
+ dp[0] = 1;
+ int[] prefix = new int[n + 1];
+ prefix[0] = 1;
+ int[] maxDeque = new int[n];
+ int maxFront = 0;
+ int maxBack = 0;
+ int[] minDeque = new int[n];
+ int minFront = 0;
+ int minBack = 0;
+ int start = 0;
+ for (int end = 0; end < n; end++) {
+ while (maxBack > maxFront && nums[maxDeque[maxBack - 1]] <= nums[end]) {
+ maxBack--;
+ }
+ maxDeque[maxBack++] = end;
+ while (minBack > minFront && nums[minDeque[minBack - 1]] >= nums[end]) {
+ minBack--;
+ }
+ minDeque[minBack++] = end;
+ while (nums[maxDeque[maxFront]] - nums[minDeque[minFront]] > k) {
+ if (maxDeque[maxFront] == start) {
+ maxFront++;
+ }
+ if (minDeque[minFront] == start) {
+ minFront++;
+ }
+ start++;
+ }
+ int sum = prefix[end] - (start > 0 ? prefix[start - 1] : 0);
+ if (sum < 0) {
+ sum += MOD;
+ }
+ dp[end + 1] = sum % MOD;
+ prefix[end + 1] = (prefix[end] + dp[end + 1]) % MOD;
+ }
+ return dp[n];
+ }
+}
diff --git a/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/readme.md b/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/readme.md
new file mode 100644
index 000000000..7bb809d52
--- /dev/null
+++ b/src/main/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/readme.md
@@ -0,0 +1,45 @@
+3578\. Count Partitions With Max-Min Difference at Most K
+
+Medium
+
+You are given an integer array `nums` and an integer `k`. Your task is to partition `nums` into one or more **non-empty** contiguous segments such that in each segment, the difference between its **maximum** and **minimum** elements is **at most** `k`.
+
+Return the total number of ways to partition `nums` under this condition.
+
+Since the answer may be too large, return it **modulo** 109 + 7
.
+
+**Example 1:**
+
+**Input:** nums = [9,4,1,3,7], k = 4
+
+**Output:** 6
+
+**Explanation:**
+
+There are 6 valid partitions where the difference between the maximum and minimum elements in each segment is at most `k = 4`:
+
+* `[[9], [4], [1], [3], [7]]`
+* `[[9], [4], [1], [3, 7]]`
+* `[[9], [4], [1, 3], [7]]`
+* `[[9], [4, 1], [3], [7]]`
+* `[[9], [4, 1], [3, 7]]`
+* `[[9], [4, 1, 3], [7]]`
+
+**Example 2:**
+
+**Input:** nums = [3,3,4], k = 0
+
+**Output:** 2
+
+**Explanation:**
+
+There are 2 valid partitions that satisfy the given conditions:
+
+* `[[3], [3], [4]]`
+* `[[3, 3], [4]]`
+
+**Constraints:**
+
+* 2 <= nums.length <= 5 * 104
+* 1 <= nums[i] <= 109
+* 0 <= k <= 109
\ No newline at end of file
diff --git a/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/Solution.java b/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/Solution.java
new file mode 100644
index 000000000..2e4ffbee7
--- /dev/null
+++ b/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/Solution.java
@@ -0,0 +1,47 @@
+package g3501_3600.s3579_minimum_steps_to_convert_string_with_operations;
+
+// #Hard #String #Dynamic_Programming #Greedy
+// #2025_06_10_Time_50_ms_(98.37%)_Space_45.06_MB_(98.37%)
+
+public class Solution {
+ public int minOperations(String word1, String word2) {
+ int[] dp = new int[word1.length()];
+ int[][] count = new int[26][26];
+ for (int i = 0; i < word1.length(); i++) {
+ dp[i] = Integer.MAX_VALUE;
+ }
+ for (int i = 0; i < word1.length(); i++) {
+ for (int j = i; j >= 0; j--) {
+ int c1 = 0;
+ int c2 = 0;
+ for (int k1 = j, k2 = j; k1 <= i && k2 <= i; k1++, k2++) {
+ int[] ints = count[word2.charAt(k2) - 'a'];
+ if (ints[word1.charAt(k1) - 'a'] > 0) {
+ ints[word1.charAt(k1) - 'a']--;
+ } else if (word1.charAt(k1) != word2.charAt(k2)) {
+ count[word1.charAt(k1) - 'a'][word2.charAt(k2) - 'a']++;
+ c1++;
+ }
+ }
+ for (int k1 = j, k2 = j; k1 <= i && k2 <= i; k1++, k2++) {
+ count[word1.charAt(k1) - 'a'][word2.charAt(k2) - 'a'] = 0;
+ }
+ dp[i] = Math.min(dp[i], j - 1 < 0 ? c1 : dp[j - 1] + c1);
+ for (int k1 = j, k2 = i; k1 <= i && k2 >= j; k1++, k2--) {
+ int[] ints = count[word2.charAt(k2) - 'a'];
+ if (ints[word1.charAt(k1) - 'a'] > 0) {
+ ints[word1.charAt(k1) - 'a']--;
+ } else if (word1.charAt(k1) - 'a' != word2.charAt(k2) - 'a') {
+ count[word1.charAt(k1) - 'a'][word2.charAt(k2) - 'a']++;
+ c2++;
+ }
+ }
+ for (int k1 = j, k2 = i; k1 <= i && k2 >= j; k1++, k2--) {
+ count[word1.charAt(k1) - 'a'][word2.charAt(k2) - 'a'] = 0;
+ }
+ dp[i] = Math.min(dp[i], j - 1 < 0 ? c2 + 1 : dp[j - 1] + c2 + 1);
+ }
+ }
+ return dp[word1.length() - 1];
+ }
+}
diff --git a/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/readme.md b/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/readme.md
new file mode 100644
index 000000000..daca34910
--- /dev/null
+++ b/src/main/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/readme.md
@@ -0,0 +1,73 @@
+3579\. Minimum Steps to Convert String with Operations
+
+Hard
+
+You are given two strings, `word1` and `word2`, of equal length. You need to transform `word1` into `word2`.
+
+For this, divide `word1` into one or more **contiguous **substring****. For each substring `substr` you can perform the following operations:
+
+1. **Replace:** Replace the character at any one index of `substr` with another lowercase English letter.
+
+2. **Swap:** Swap any two characters in `substr`.
+
+3. **Reverse Substring:** Reverse `substr`.
+
+
+Each of these counts as **one** operation and each character of each substring can be used in each type of operation at most once (i.e. no single index may be involved in more than one replace, one swap, or one reverse).
+
+Return the **minimum number of operations** required to transform `word1` into `word2`.
+
+**Example 1:**
+
+**Input:** word1 = "abcdf", word2 = "dacbe"
+
+**Output:** 4
+
+**Explanation:**
+
+Divide `word1` into `"ab"`, `"c"`, and `"df"`. The operations are:
+
+* For the substring `"ab"`,
+ * Perform operation of type 3 on `"ab" -> "ba"`.
+ * Perform operation of type 1 on `"ba" -> "da"`.
+* For the substring `"c"` do no operations.
+* For the substring `"df"`,
+ * Perform operation of type 1 on `"df" -> "bf"`.
+ * Perform operation of type 1 on `"bf" -> "be"`.
+
+**Example 2:**
+
+**Input:** word1 = "abceded", word2 = "baecfef"
+
+**Output:** 4
+
+**Explanation:**
+
+Divide `word1` into `"ab"`, `"ce"`, and `"ded"`. The operations are:
+
+* For the substring `"ab"`,
+ * Perform operation of type 2 on `"ab" -> "ba"`.
+* For the substring `"ce"`,
+ * Perform operation of type 2 on `"ce" -> "ec"`.
+* For the substring `"ded"`,
+ * Perform operation of type 1 on `"ded" -> "fed"`.
+ * Perform operation of type 1 on `"fed" -> "fef"`.
+
+**Example 3:**
+
+**Input:** word1 = "abcdef", word2 = "fedabc"
+
+**Output:** 2
+
+**Explanation:**
+
+Divide `word1` into `"abcdef"`. The operations are:
+
+* For the substring `"abcdef"`,
+ * Perform operation of type 3 on `"abcdef" -> "fedcba"`.
+ * Perform operation of type 2 on `"fedcba" -> "fedabc"`.
+
+**Constraints:**
+
+* `1 <= word1.length == word2.length <= 100`
+* `word1` and `word2` consist only of lowercase English letters.
\ No newline at end of file
diff --git a/src/test/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/SolutionTest.java b/src/test/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/SolutionTest.java
new file mode 100644
index 000000000..320f60a15
--- /dev/null
+++ b/src/test/java/g3501_3600/s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues/SolutionTest.java
@@ -0,0 +1,25 @@
+package g3501_3600.s3572_maximize_ysum_by_picking_a_triplet_of_distinct_xvalues;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void maxSumDistinctTriplet() {
+ assertThat(
+ new Solution()
+ .maxSumDistinctTriplet(
+ new int[] {1, 2, 1, 3, 2}, new int[] {5, 3, 4, 6, 2}),
+ equalTo(14));
+ }
+
+ @Test
+ void maxSumDistinctTriplet2() {
+ assertThat(
+ new Solution()
+ .maxSumDistinctTriplet(new int[] {1, 2, 1, 2}, new int[] {4, 5, 6, 7}),
+ equalTo(-1));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/SolutionTest.java b/src/test/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/SolutionTest.java
new file mode 100644
index 000000000..498f2e842
--- /dev/null
+++ b/src/test/java/g3501_3600/s3573_best_time_to_buy_and_sell_stock_v/SolutionTest.java
@@ -0,0 +1,20 @@
+package g3501_3600.s3573_best_time_to_buy_and_sell_stock_v;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void maximumProfit() {
+ assertThat(new Solution().maximumProfit(new int[] {1, 7, 9, 8, 2}, 2), equalTo(14L));
+ }
+
+ @Test
+ void maximumProfit2() {
+ assertThat(
+ new Solution().maximumProfit(new int[] {12, 16, 19, 19, 8, 1, 19, 13, 9}, 3),
+ equalTo(36L));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3574_maximize_subarray_gcd_score/SolutionTest.java b/src/test/java/g3501_3600/s3574_maximize_subarray_gcd_score/SolutionTest.java
new file mode 100644
index 000000000..f47b5578e
--- /dev/null
+++ b/src/test/java/g3501_3600/s3574_maximize_subarray_gcd_score/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3501_3600.s3574_maximize_subarray_gcd_score;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void maxGCDScore() {
+ assertThat(new Solution().maxGCDScore(new int[] {2, 4}, 1), equalTo(8L));
+ }
+
+ @Test
+ void maxGCDScore2() {
+ assertThat(new Solution().maxGCDScore(new int[] {3, 5, 7}, 2), equalTo(14L));
+ }
+
+ @Test
+ void maxGCDScore3() {
+ assertThat(new Solution().maxGCDScore(new int[] {5, 5, 5}, 1), equalTo(15L));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3575_maximum_good_subtree_score/SolutionTest.java b/src/test/java/g3501_3600/s3575_maximum_good_subtree_score/SolutionTest.java
new file mode 100644
index 000000000..dce805cf9
--- /dev/null
+++ b/src/test/java/g3501_3600/s3575_maximum_good_subtree_score/SolutionTest.java
@@ -0,0 +1,34 @@
+package g3501_3600.s3575_maximum_good_subtree_score;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void goodSubtreeSum() {
+ assertThat(new Solution().goodSubtreeSum(new int[] {2, 3}, new int[] {-1, 0}), equalTo(8));
+ }
+
+ @Test
+ void goodSubtreeSum2() {
+ assertThat(
+ new Solution().goodSubtreeSum(new int[] {1, 5, 2}, new int[] {-1, 0, 0}),
+ equalTo(15));
+ }
+
+ @Test
+ void goodSubtreeSum3() {
+ assertThat(
+ new Solution().goodSubtreeSum(new int[] {34, 1, 2}, new int[] {-1, 0, 1}),
+ equalTo(42));
+ }
+
+ @Test
+ void goodSubtreeSum4() {
+ assertThat(
+ new Solution().goodSubtreeSum(new int[] {3, 22, 5}, new int[] {-1, 0, 1}),
+ equalTo(18));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3576_transform_array_to_all_equal_elements/SolutionTest.java b/src/test/java/g3501_3600/s3576_transform_array_to_all_equal_elements/SolutionTest.java
new file mode 100644
index 000000000..d0b864950
--- /dev/null
+++ b/src/test/java/g3501_3600/s3576_transform_array_to_all_equal_elements/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3501_3600.s3576_transform_array_to_all_equal_elements;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void canMakeEqual() {
+ assertThat(new Solution().canMakeEqual(new int[] {1, -1, 1, -1, 1}, 3), equalTo(true));
+ }
+
+ @Test
+ void canMakeEqual2() {
+ assertThat(new Solution().canMakeEqual(new int[] {-1, -1, -1, 1, 1, 1}, 5), equalTo(false));
+ }
+
+ @Test
+ void canMakeEqual3() {
+ assertThat(new Solution().canMakeEqual(new int[] {1}, 3), equalTo(true));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/SolutionTest.java b/src/test/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/SolutionTest.java
new file mode 100644
index 000000000..ed457851f
--- /dev/null
+++ b/src/test/java/g3501_3600/s3577_count_the_number_of_computer_unlocking_permutations/SolutionTest.java
@@ -0,0 +1,18 @@
+package g3501_3600.s3577_count_the_number_of_computer_unlocking_permutations;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void countPermutations() {
+ assertThat(new Solution().countPermutations(new int[] {1, 2, 3}), equalTo(2));
+ }
+
+ @Test
+ void countPermutations2() {
+ assertThat(new Solution().countPermutations(new int[] {3, 3, 3, 4, 4, 4}), equalTo(0));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/SolutionTest.java b/src/test/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/SolutionTest.java
new file mode 100644
index 000000000..8e0c87733
--- /dev/null
+++ b/src/test/java/g3501_3600/s3578_count_partitions_with_max_min_difference_at_most_k/SolutionTest.java
@@ -0,0 +1,18 @@
+package g3501_3600.s3578_count_partitions_with_max_min_difference_at_most_k;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void countPartitions() {
+ assertThat(new Solution().countPartitions(new int[] {9, 4, 1, 3, 7}, 4), equalTo(6));
+ }
+
+ @Test
+ void countPartitions2() {
+ assertThat(new Solution().countPartitions(new int[] {3, 3, 4}, 0), equalTo(2));
+ }
+}
diff --git a/src/test/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/SolutionTest.java b/src/test/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/SolutionTest.java
new file mode 100644
index 000000000..4c19c168d
--- /dev/null
+++ b/src/test/java/g3501_3600/s3579_minimum_steps_to_convert_string_with_operations/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3501_3600.s3579_minimum_steps_to_convert_string_with_operations;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void minOperations() {
+ assertThat(new Solution().minOperations("abcdf", "dacbe"), equalTo(4));
+ }
+
+ @Test
+ void minOperations2() {
+ assertThat(new Solution().minOperations("abceded", "baecfef"), equalTo(4));
+ }
+
+ @Test
+ void minOperations3() {
+ assertThat(new Solution().minOperations("abcdef", "fedabc"), equalTo(2));
+ }
+}