diff --git a/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/Solution.java b/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/Solution.java
new file mode 100644
index 000000000..2cf37828c
--- /dev/null
+++ b/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/Solution.java
@@ -0,0 +1,22 @@
+package g3701_3800.s3760_maximum_substrings_with_distinct_start;
+
+// #Medium #String #Hash_Table #Senior #Weekly_Contest_478
+// #2026_05_08_Time_5_ms_(98.92%)_Space_47.79_MB_(74.99%)
+
+public class Solution {
+ public int maxDistinct(String s) {
+ int mask = 0;
+ int res = 0;
+ for (char c : s.toCharArray()) {
+ int bit = 1 << (c - 'a');
+ if ((mask & bit) == 0) {
+ mask |= bit;
+ res++;
+ if (res == 26) {
+ break;
+ }
+ }
+ }
+ return res;
+ }
+}
diff --git a/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/readme.md b/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/readme.md
new file mode 100644
index 000000000..d9243db58
--- /dev/null
+++ b/src/main/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/readme.md
@@ -0,0 +1,45 @@
+3760\. Maximum Substrings With Distinct Start
+
+Medium
+
+You are given a string `s` consisting of lowercase English letters.
+
+Return an integer denoting the **maximum** number of substring you can split `s` into such that each **substring** starts with a **distinct** character (i.e., no two substrings start with the same character).
+
+**Example 1:**
+
+**Input:** s = "abab"
+
+**Output:** 2
+
+**Explanation:**
+
+* Split `"abab"` into `"a"` and `"bab"`.
+* Each substring starts with a distinct character i.e `'a'` and `'b'`. Thus, the answer is 2.
+
+**Example 2:**
+
+**Input:** s = "abcd"
+
+**Output:** 4
+
+**Explanation:**
+
+* Split `"abcd"` into `"a"`, `"b"`, `"c"`, and `"d"`.
+* Each substring starts with a distinct character. Thus, the answer is 4.
+
+**Example 3:**
+
+**Input:** s = "aaaa"
+
+**Output:** 1
+
+**Explanation:**
+
+* All characters in `"aaaa"` are `'a'`.
+* Only one substring can start with `'a'`. Thus, the answer is 1.
+
+**Constraints:**
+
+* 1 <= s.length <= 105
+* `s` consists of lowercase English letters.
\ No newline at end of file
diff --git a/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/Solution.java b/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/Solution.java
new file mode 100644
index 000000000..96693e412
--- /dev/null
+++ b/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/Solution.java
@@ -0,0 +1,26 @@
+package g3701_3800.s3761_minimum_absolute_distance_between_mirror_pairs;
+
+// #Medium #Array #Hash_Table #Math #Staff #Weekly_Contest_478
+// #2026_05_08_Time_49_ms_(84.83%)_Space_95.13_MB_(49.31%)
+
+import java.util.HashMap;
+
+public class Solution {
+ public int minMirrorPairDistance(int[] nums) {
+ int res = 100000;
+ int i = 0;
+ HashMap seen = new HashMap<>();
+ for (int n : nums) {
+ int r;
+ if (seen.containsKey(n)) {
+ res = Math.min(res, i - seen.get(n));
+ }
+ for (r = 0; n > 0; n /= 10) {
+ r = r * 10 + (n % 10);
+ }
+ seen.put(r, i++);
+ }
+
+ return res == 100000 ? -1 : res;
+ }
+}
diff --git a/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/readme.md b/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/readme.md
new file mode 100644
index 000000000..7333c65d2
--- /dev/null
+++ b/src/main/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/readme.md
@@ -0,0 +1,56 @@
+3761\. Minimum Absolute Distance Between Mirror Pairs
+
+Medium
+
+You are given an integer array `nums`.
+
+A **mirror pair** is a pair of indices `(i, j)` such that:
+
+* `0 <= i < j < nums.length`, and
+* `reverse(nums[i]) == nums[j]`, where `reverse(x)` denotes the integer formed by reversing the digits of `x`. Leading zeros are omitted after reversing, for example `reverse(120) = 21`.
+
+Return the **minimum** absolute distance between the indices of any mirror pair. The absolute distance between indices `i` and `j` is `abs(i - j)`.
+
+If no mirror pair exists, return `-1`.
+
+**Example 1:**
+
+**Input:** nums = [12,21,45,33,54]
+
+**Output:** 1
+
+**Explanation:**
+
+The mirror pairs are:
+
+* (0, 1) since `reverse(nums[0]) = reverse(12) = 21 = nums[1]`, giving an absolute distance `abs(0 - 1) = 1`.
+* (2, 4) since `reverse(nums[2]) = reverse(45) = 54 = nums[4]`, giving an absolute distance `abs(2 - 4) = 2`.
+
+The minimum absolute distance among all pairs is 1.
+
+**Example 2:**
+
+**Input:** nums = [120,21]
+
+**Output:** 1
+
+**Explanation:**
+
+There is only one mirror pair (0, 1) since `reverse(nums[0]) = reverse(120) = 21 = nums[1]`.
+
+The minimum absolute distance is 1.
+
+**Example 3:**
+
+**Input:** nums = [21,120]
+
+**Output:** \-1
+
+**Explanation:**
+
+There are no mirror pairs in the array.
+
+**Constraints:**
+
+* 1 <= nums.length <= 105
+* 1 <= nums[i] <= 109
\ No newline at end of file
diff --git a/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/Solution.java b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/Solution.java
new file mode 100644
index 000000000..f95f68fc3
--- /dev/null
+++ b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/Solution.java
@@ -0,0 +1,222 @@
+package g3701_3800.s3762_minimum_operations_to_equalize_subarrays;
+
+// #Hard #Array #Math #Binary_Search #Segment_Tree #Weekly_Contest_478 #Principal
+// #2026_05_08_Time_528_ms_(100.00%)_Space_267.97_MB_(76.92%)
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Solution {
+ private static class MNode {
+ int l;
+ int r;
+ int[] vals;
+ long[] pref;
+ MNode left;
+ MNode right;
+
+ MNode(int l, int r) {
+ this.l = l;
+ this.r = r;
+ }
+ }
+
+ private static class Group {
+ int[] pos;
+ int[] val;
+ long[] prefPos;
+ MNode root;
+ int minv;
+ int maxv;
+ }
+
+ private static int lowerBound(int[] a, int x) {
+ int l = 0;
+ int r = a.length;
+ while (l < r) {
+ int m = (l + r) >>> 1;
+ if (a[m] >= x) {
+ r = m;
+ } else {
+ l = m + 1;
+ }
+ }
+ return l;
+ }
+
+ private int upperBound(int[] a, int x) {
+ int l = 0;
+ int r = a.length;
+ while (l < r) {
+ int m = (l + r) >>> 1;
+ if (a[m] > x) {
+ r = m;
+ } else {
+ l = m + 1;
+ }
+ }
+ return l;
+ }
+
+ private MNode buildMerge(int[] arr, int l, int r) {
+ MNode node = new MNode(l, r);
+ if (l == r) {
+ node.vals = new int[] {arr[l]};
+ node.pref = new long[] {arr[l]};
+ return node;
+ }
+ int m = (l + r) >>> 1;
+ node.left = buildMerge(arr, l, m);
+ node.right = buildMerge(arr, m + 1, r);
+ int[] a = node.left.vals;
+ int[] b = node.right.vals;
+ int na = a.length;
+ int nb = b.length;
+ int[] c = new int[na + nb];
+ long[] pref = new long[na + nb];
+ int ia = 0;
+ int ib = 0;
+ int k = 0;
+ while (ia < na && ib < nb) {
+ if (a[ia] <= b[ib]) {
+ c[k++] = a[ia++];
+ } else {
+ c[k++] = b[ib++];
+ }
+ }
+ while (ia < na) {
+ c[k++] = a[ia++];
+ }
+ while (ib < nb) {
+ c[k++] = b[ib++];
+ }
+ pref[0] = c[0];
+ for (int i = 1; i < c.length; i++) {
+ pref[i] = pref[i - 1] + c[i];
+ }
+ node.vals = c;
+ node.pref = pref;
+ return node;
+ }
+
+ private int countLE(MNode node, int ql, int qr, int x) {
+ if (node == null || ql > node.r || qr < node.l) {
+ return 0;
+ }
+ if (ql <= node.l && node.r <= qr) {
+ int idx = upperBound(node.vals, x) - 1;
+ return idx < 0 ? 0 : idx + 1;
+ }
+ return countLE(node.left, ql, qr, x) + countLE(node.right, ql, qr, x);
+ }
+
+ private long sumLE(MNode node, int ql, int qr, int x) {
+ if (node == null || ql > node.r || qr < node.l) {
+ return 0L;
+ }
+ if (ql <= node.l && node.r <= qr) {
+ int idx = upperBound(node.vals, x) - 1;
+ return idx < 0 ? 0L : node.pref[idx];
+ }
+ return sumLE(node.left, ql, qr, x) + sumLE(node.right, ql, qr, x);
+ }
+
+ public long[] minOperations(int[] nums, int k, int[][] queries) {
+ Map groupHashMap = buildGroups(nums, k);
+ long[] ans = new long[queries.length];
+ for (int qi = 0; qi < queries.length; qi++) {
+ ans[qi] = processQuery(nums, queries[qi], groupHashMap, k);
+ }
+ return ans;
+ }
+
+ private Map buildGroups(int[] nums, int k) {
+ Map> map = new HashMap<>();
+ for (int i = 0; i < nums.length; i++) {
+ int rem = nums[i] % k;
+ int value = nums[i] / k;
+ map.computeIfAbsent(rem, z -> new ArrayList<>()).add(new int[] {i, value});
+ }
+ Map groupHashMap = new HashMap<>();
+ for (Map.Entry> entry : map.entrySet()) {
+ groupHashMap.put(entry.getKey(), createGroup(entry.getValue()));
+ }
+ return groupHashMap;
+ }
+
+ private Group createGroup(ArrayList arr) {
+ arr.sort(Comparator.comparingInt(a -> a[0]));
+ int size = arr.size();
+ int[] pos = new int[size];
+ int[] val = new int[size];
+ long[] prefPos = new long[size];
+ int min = Integer.MAX_VALUE;
+ int max = Integer.MIN_VALUE;
+ for (int i = 0; i < size; i++) {
+ pos[i] = arr.get(i)[0];
+ val[i] = arr.get(i)[1];
+ min = Math.min(min, val[i]);
+ max = Math.max(max, val[i]);
+ prefPos[i] = i == 0 ? val[i] : prefPos[i - 1] + val[i];
+ }
+ Group group = new Group();
+ group.pos = pos;
+ group.val = val;
+ group.prefPos = prefPos;
+ group.minv = min;
+ group.maxv = max;
+ if (size > 0) {
+ group.root = buildMerge(val, 0, size - 1);
+ }
+ return group;
+ }
+
+ private long processQuery(int[] nums, int[] query, Map groupHashMap, int k) {
+ int left = query[0];
+ int right = query[1];
+ int rem = nums[left] % k;
+ Group group = groupHashMap.get(rem);
+ if (group == null) {
+ return -1;
+ }
+ int l = lowerBound(group.pos, left);
+ int r = upperBound(group.pos, right) - 1;
+ if (!isValidRange(left, right, l, r)) {
+ return -1;
+ }
+ return calculateOperations(group, l, r);
+ }
+
+ private boolean isValidRange(int left, int right, int l, int r) {
+ return l <= r && (r - l + 1 == right - left + 1);
+ }
+
+ private long calculateOperations(Group group, int l, int r) {
+ int count = r - l + 1;
+ int median = findMedian(group, l, r, count);
+ long leftCount = countLE(group.root, l, r, median);
+ long leftSum = sumLE(group.root, l, r, median);
+ long total = group.prefPos[r] - (l == 0 ? 0L : group.prefPos[l - 1]);
+ long rightSum = total - leftSum;
+ long rightCount = count - leftCount;
+ return median * leftCount - leftSum + rightSum - median * rightCount;
+ }
+
+ private int findMedian(Group group, int l, int r, int count) {
+ int need = (count + 1) / 2;
+ int low = group.minv;
+ int high = group.maxv;
+ while (low < high) {
+ int mid = low + ((high - low) >>> 1);
+ int currentCount = countLE(group.root, l, r, mid);
+ if (currentCount >= need) {
+ high = mid;
+ } else {
+ low = mid + 1;
+ }
+ }
+ return low;
+ }
+}
diff --git a/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/readme.md b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/readme.md
new file mode 100644
index 000000000..f0f048abe
--- /dev/null
+++ b/src/main/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/readme.md
@@ -0,0 +1,57 @@
+3762\. Minimum Operations to Equalize Subarrays
+
+Hard
+
+You are given an integer array `nums` and an integer `k`.
+
+In one operation, you can **increase or decrease** any element of `nums` by **exactly** `k`.
+
+You are also given a 2D integer array `queries`, where each queries[i] = [li, ri].
+
+For each query, find the **minimum** number of operations required to make **all** elements in the **non-empty subarrays** nums[li..ri] **equal**. If it is impossible, the answer for that query is `-1`.
+
+Return an array `ans`, where `ans[i]` is the answer for the ith query.
+
+**Example 1:**
+
+**Input:** nums = [1,4,7], k = 3, queries = [[0,1],[0,2]]
+
+**Output:** [1,2]
+
+**Explanation:**
+
+One optimal set of operations:
+
+| `i` | `[l_i, r_i]` | `nums[l_i..r_i]` | Possibility | Operations | Final `nums[l_i..r_i]` | `ans[i]` |
+|---|---|---|---|---|---|---|
+| 0 | [0, 1] | [1, 4] | Yes | `nums[0] + k = 1 + 3 = 4 = nums[1]` | [4, 4] | 1 |
+| 1 | [0, 2] | [1, 4, 7] | Yes | `nums[0] + k = 1 + 3 = 4 = nums[1]`
`nums[2] - k = 7 - 3 = 4 = nums[1]` | [4, 4, 4] | 2 |
+
+Thus, `ans = [1, 2]`.
+
+**Example 2:**
+
+**Input:** nums = [1,2,4], k = 2, queries = [[0,2],[0,0],[1,2]]
+
+**Output:** [-1,0,1]
+
+**Explanation:**
+
+One optimal set of operations:
+
+| `i` | `[l_i, r_i]` | `nums[l_i..r_i]` | Possibility | Operations | Final `nums[l_i..r_i]` | `ans[i]` |
+|---|---|---|---|---|---|---|
+| 0 | [0, 2] | [1, 2, 4] | No | - | [1, 2, 4] | -1 |
+| 1 | [0, 0] | [1] | Yes | Already equal | [1] | 0 |
+| 2 | [1, 2] | [2, 4] | Yes | `nums[1] + k = 2 + 2 = 4 = nums[2]` | [4, 4] | 1 |
+
+Thus, `ans = [-1, 0, 1]`.
+
+**Constraints:**
+
+* 1 <= n == nums.length <= 4 × 104
+* 1 <= nums[i] <= 109
+* 1 <= k <= 109
+* 1 <= queries.length <= 4 × 104
+* queries[i] = [li, ri]
+* 0 <= li <= ri <= n - 1
diff --git a/src/main/java/g3701_3800/s3764_most_common_course_pairs/readme.md b/src/main/java/g3701_3800/s3764_most_common_course_pairs/readme.md
new file mode 100644
index 000000000..492a1b7d6
--- /dev/null
+++ b/src/main/java/g3701_3800/s3764_most_common_course_pairs/readme.md
@@ -0,0 +1,84 @@
+3764\. Most Common Course Pairs
+
+Hard
+
+Table: `course_completions`
+
+ +-------------------+---------+
+ | Column Name | Type |
+ +-------------------+---------+
+ | user_id | int |
+ | course_id | int |
+ | course_name | varchar |
+ | completion_date | date |
+ | course_rating | int |
+ +-------------------+---------+
+ (user_id, course_id) is the combination of columns with unique values for this table.
+ Each row represents a completed course by a user with their rating (1-5 scale).
+
+Write a solution to identify **skill mastery pathways** by analyzing course completion sequences among top-performing students:
+
+* Consider only **top-performing students** (those who completed **at least** `5` **courses** with an **average rating of** `4` **or higher**).
+* For each top performer, identify the **sequence of courses** they completed in chronological order.
+* Find all **consecutive course pairs** (`Course A → Course B`) taken by these students.
+* Return the **pair frequency**, identifying which course transitions are most common among high achievers.
+
+Return _the result table ordered by_ _pair frequency in **descending** order_ _and then by first course name and second course name in **ascending** order_.
+
+The result format is in the following example.
+
+**Example:**
+
+**Input:**
+
+course_completions table:
+
+ +---------+-----------+---------------------+-----------------+---------------+
+ | user_id | course_id | course_name | completion_date | course_rating |
+ +---------+-----------+---------------------+-----------------+---------------+
+ | 1 | 101 | Python Basics | 2024-01-05 | 5 |
+ | 1 | 102 | SQL Fundamentals | 2024-02-10 | 4 |
+ | 1 | 103 | JavaScript | 2024-03-15 | 5 |
+ | 1 | 104 | React Basics | 2024-04-20 | 4 |
+ | 1 | 105 | Node.js | 2024-05-25 | 5 |
+ | 1 | 106 | Docker | 2024-06-30 | 4 |
+ | 2 | 101 | Python Basics | 2024-01-08 | 4 |
+ | 2 | 104 | React Basics | 2024-02-14 | 5 |
+ | 2 | 105 | Node.js | 2024-03-20 | 4 |
+ | 2 | 106 | Docker | 2024-04-25 | 5 |
+ | 2 | 107 | AWS Fundamentals | 2024-05-30 | 4 |
+ | 3 | 101 | Python Basics | 2024-01-10 | 3 |
+ | 3 | 102 | SQL Fundamentals | 2024-02-12 | 3 |
+ | 3 | 103 | JavaScript | 2024-03-18 | 3 |
+ | 3 | 104 | React Basics | 2024-04-22 | 2 |
+ | 3 | 105 | Node.js | 2024-05-28 | 3 |
+ | 4 | 101 | Python Basics | 2024-01-12 | 5 |
+ | 4 | 108 | Data Science | 2024-02-16 | 5 |
+ | 4 | 109 | Machine Learning | 2024-03-22 | 5 |
+ +---------+-----------+---------------------+-----------------+---------------+
+
+**Output:**
+
+ +------------------+-------------------+------------------+
+ | first_course | second_course | transition_count |
+ +------------------+-------------------+------------------+
+ | Node.js | Docker | 2 |
+ | React Basics | Node.js | 2 |
+ | Docker | AWS Fundamentals | 1 |
+ | JavaScript | React Basics | 1 |
+ | Python Basics | React Basics | 1 |
+ | Python Basics | SQL Fundamentals | 1 |
+ | SQL Fundamentals | JavaScript | 1 |
+ +------------------+-------------------+------------------+
+**Explanation:**
+
+* **User 1**: Completed 6 courses with average rating 4.5 (qualifies as top performer)
+* **User 2**: Completed 5 courses with average rating 4.4 (qualifies as top performer)
+* **User 3**: Completed 5 courses but average rating is 2.8 (does not qualify)
+* **User 4**: Completed only 3 courses (does not qualify)
+* **Course Pairs Among Top Performers**:
+ * User 1: Python Basics → SQL Fundamentals → JavaScript → React Basics → Node.js → Docker
+ * User 2: Python Basics → React Basics → Node.js → Docker → AWS Fundamentals
+ * Most common transitions: Node.js → Docker (2 times), React Basics → Node.js (2 times)
+
+Results are ordered by transition_count in descending order, then by first_course in ascending order, and then by second_course in ascending order.
diff --git a/src/main/java/g3701_3800/s3764_most_common_course_pairs/script.sql b/src/main/java/g3701_3800/s3764_most_common_course_pairs/script.sql
new file mode 100644
index 000000000..4ea151824
--- /dev/null
+++ b/src/main/java/g3701_3800/s3764_most_common_course_pairs/script.sql
@@ -0,0 +1,27 @@
+# Write your MySQL query statement below
+# #Hard #2026_05_08_Time_262_ms_(63.61%)_Space_0.0_MB_(100.00%)
+-- Find the most common course-to-next-course transitions
+-- among engaged users (>=5 courses, avg rating >= 4)
+SELECT
+ course_name AS first_course,
+ next_course AS second_course,
+ COUNT(*) AS transition_count
+FROM (
+ SELECT
+ *,
+ LEAD(course_name) OVER (
+ PARTITION BY user_id
+ ORDER BY completion_date
+ ) AS next_course
+ FROM course_completions
+ WHERE user_id IN (
+ SELECT user_id
+ FROM course_completions
+ GROUP BY user_id
+ HAVING COUNT(course_id) >= 5
+ AND AVG(course_rating) >= 4
+ )
+) AS t
+WHERE next_course IS NOT NULL
+GROUP BY course_name, next_course
+ORDER BY transition_count DESC, first_course ASC, second_course ASC;
diff --git a/src/main/java/g3701_3800/s3765_complete_prime_number/Solution.java b/src/main/java/g3701_3800/s3765_complete_prime_number/Solution.java
new file mode 100644
index 000000000..e00537b2d
--- /dev/null
+++ b/src/main/java/g3701_3800/s3765_complete_prime_number/Solution.java
@@ -0,0 +1,36 @@
+package g3701_3800.s3765_complete_prime_number;
+
+// #Medium #Math #Enumeration #Number_Theory #Senior #Biweekly_Contest_171
+// #2026_05_08_Time_2_ms_(91.62%)_Space_42.93_MB_(55.39%)
+
+public class Solution {
+ private boolean isPrime(int n) {
+ if (n != 2 && n % 2 == 0) {
+ return false;
+ }
+ for (int i = 3; i * i <= n; i += 2) {
+ if (n % i == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean completePrime(int num) {
+ int y = 0;
+ int z = 1;
+ int x = num;
+ while (x > 0) {
+ y = z * (x % 10) + y;
+ if (y == 1 || !isPrime(y)) {
+ return false;
+ }
+ if (x == 1 || !isPrime(x)) {
+ return false;
+ }
+ x /= 10;
+ z *= 10;
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/g3701_3800/s3765_complete_prime_number/readme.md b/src/main/java/g3701_3800/s3765_complete_prime_number/readme.md
new file mode 100644
index 000000000..36922bd1f
--- /dev/null
+++ b/src/main/java/g3701_3800/s3765_complete_prime_number/readme.md
@@ -0,0 +1,53 @@
+3765\. Complete Prime Number
+
+Medium
+
+You are given an integer `num`.
+
+A number `num` is called a **Complete Prime Number** if every **prefix** and every **suffix** of `num` is **prime**.
+
+Return `true` if `num` is a Complete Prime Number, otherwise return `false`.
+
+**Note**:
+
+* A **prefix** of a number is formed by the **first** `k` digits of the number.
+* A **suffix** of a number is formed by the **last** `k` digits of the number.
+* Single-digit numbers are considered Complete Prime Numbers only if they are **prime**.
+
+**Example 1:**
+
+**Input:** num = 23
+
+**Output:** true
+
+**Explanation:**
+
+* Prefixes of `num = 23` are 2 and 23, both are prime.
+* Suffixes of `num = 23` are 3 and 23, both are prime.
+* All prefixes and suffixes are prime, so 23 is a Complete Prime Number and the answer is `true`.
+
+**Example 2:**
+
+**Input:** num = 39
+
+**Output:** false
+
+**Explanation:**
+
+* Prefixes of `num = 39` are 3 and 39. 3 is prime, but 39 is not prime.
+* Suffixes of `num = 39` are 9 and 39. Both 9 and 39 are not prime.
+* At least one prefix or suffix is not prime, so 39 is not a Complete Prime Number and the answer is `false`.
+
+**Example 3:**
+
+**Input:** num = 7
+
+**Output:** true
+
+**Explanation:**
+
+* 7 is prime, so all its prefixes and suffixes are prime and the answer is `true`.
+
+**Constraints:**
+
+* 1 <= num <= 109
\ No newline at end of file
diff --git a/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/Solution.java b/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/Solution.java
new file mode 100644
index 000000000..cbc5a7a17
--- /dev/null
+++ b/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/Solution.java
@@ -0,0 +1,52 @@
+package g3701_3800.s3766_minimum_operations_to_make_binary_palindrome;
+
+// #Medium #Array #Binary_Search #Two_Pointers #Bit_Manipulation #Staff #Biweekly_Contest_171
+// #2026_05_08_Time_54_ms_(82.69%)_Space_47.43_MB_(64.42%)
+
+public class Solution {
+ private int binlen(int n) {
+ int c = 0;
+ while (n > 0) {
+ c++;
+ n >>= 1;
+ }
+ return c;
+ }
+
+ private boolean isPal(int n) {
+ int l = 0;
+ int r = binlen(n) - 1;
+ while (l < r) {
+ if (((n >> l) & 1) != ((n >> r) & 1)) {
+ return false;
+ }
+ l++;
+ r--;
+ }
+ return true;
+ }
+
+ public int[] minOperations(int[] nums) {
+ boolean[] binary = new boolean[5050];
+ int[] ans = new int[nums.length];
+ for (int i = 0; i < 5050; i++) {
+ binary[i] = isPal(i);
+ }
+ for (int i = 0; i < nums.length; i++) {
+ int a = nums[i];
+ int b = nums[i];
+ int c1 = 0;
+ int c2 = 0;
+ while (!binary[a]) {
+ a--;
+ c1++;
+ }
+ while (!binary[b]) {
+ b++;
+ c2++;
+ }
+ ans[i] = Math.min(c1, c2);
+ }
+ return ans;
+ }
+}
diff --git a/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/readme.md b/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/readme.md
new file mode 100644
index 000000000..1eb6ac57a
--- /dev/null
+++ b/src/main/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/readme.md
@@ -0,0 +1,55 @@
+3766\. Minimum Operations to Make Binary Palindrome
+
+Medium
+
+You are given an integer array `nums`.
+
+For each element `nums[i]`, you may perform the following operations **any** number of times (including zero):
+
+* Increase `nums[i]` by 1, or
+* Decrease `nums[i]` by 1.
+
+A number is called a **binary palindrome** if its binary representation without leading zeros reads the same forward and backward.
+
+Your task is to return an integer array `ans`, where `ans[i]` represents the **minimum** number of operations required to convert `nums[i]` into a **binary palindrome**.
+
+**Example 1:**
+
+**Input:** nums = [1,2,4]
+
+**Output:** [0,1,1]
+
+**Explanation:**
+
+One optimal set of operations:
+
+| `nums[i]` | Binary(`nums[i]`) | Nearest Palindrome | Binary (Palindrome) | Operations Required | `ans[i]` |
+|---|---|---|---|---|---|
+| 1 | 1 | 1 | 1 | Already palindrome | 0 |
+| 2 | 10 | 3 | 11 | Increase by 1 | 1 |
+| 4 | 100 | 3 | 11 | Decrease by 1 | 1 |
+
+Thus, `ans = [0, 1, 1]`.
+
+**Example 2:**
+
+**Input:** nums = [6,7,12]
+
+**Output:** [1,0,3]
+
+**Explanation:**
+
+One optimal set of operations:
+
+| `nums[i]` | Binary(`nums[i]`) | Nearest Palindrome | Binary (Palindrome) | Operations Required | `ans[i]` |
+|---|---|---|---|---|---|
+| 6 | 110 | 5 | 101 | Decrease by 1 | 1 |
+| 7 | 111 | 7 | 111 | Already palindrome | 0 |
+| 12 | 1100 | 15 | 1111 | Increase by 3 | 3 |
+
+Thus, `ans = [1, 0, 3]`.
+
+**Constraints:**
+
+* `1 <= nums.length <= 5000`
+* `1 <= nums[i] <= 5000`
diff --git a/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java
new file mode 100644
index 000000000..c8f52ac0a
--- /dev/null
+++ b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/Solution.java
@@ -0,0 +1,30 @@
+package g3701_3800.s3767_maximize_points_after_choosing_k_tasks;
+
+// #Medium #Array #Sorting #Greedy #Heap_Priority_Queue #Staff #Biweekly_Contest_171
+// #2026_05_08_Time_21_ms_(100.00%)_Space_130.40_MB_(85.82%)
+
+import java.util.PriorityQueue;
+
+public class Solution {
+ public long maxPoints(int[] technique1, int[] technique2, int k) {
+ int n = technique1.length;
+ int use2 = n - k;
+ PriorityQueue min = new PriorityQueue<>();
+ long ans = 0;
+ for (int i = 0; i < n; ++i) {
+ int diff = technique2[i] - technique1[i];
+ if (diff > 0) {
+ if (min.size() < use2) {
+ min.offer(diff);
+ ans += diff;
+ } else if (!min.isEmpty() && min.peek() < diff) {
+ ans -= min.poll();
+ min.offer(diff);
+ ans += diff;
+ }
+ }
+ ans += technique1[i];
+ }
+ return ans;
+ }
+}
diff --git a/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/readme.md b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/readme.md
new file mode 100644
index 000000000..d61da8f1e
--- /dev/null
+++ b/src/main/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/readme.md
@@ -0,0 +1,58 @@
+3767\. Maximize Points After Choosing K Tasks
+
+Medium
+
+You are given two integer arrays, `technique1` and `technique2`, each of length `n`, where `n` represents the number of tasks to complete.
+
+* If the ith task is completed using technique 1, you earn `technique1[i]` points.
+* If it is completed using technique 2, you earn `technique2[i]` points.
+
+You are also given an integer `k`, representing the **minimum** number of tasks that **must** be completed using technique 1.
+
+You **must** complete **at least** `k` tasks using technique 1 (they do not need to be the first `k` tasks).
+
+The remaining tasks may be completed using **either** technique.
+
+Return an integer denoting the **maximum total points** you can earn.
+
+**Example 1:**
+
+**Input:** technique1 = [5,2,10], technique2 = [10,3,8], k = 2
+
+**Output:** 22
+
+**Explanation:**
+
+We must complete at least `k = 2` tasks using `technique1`.
+
+Choosing `technique1[1]` and `technique1[2]` (completed using technique 1), and `technique2[0]` (completed using technique 2), yields the maximum points: `2 + 10 + 10 = 22`.
+
+**Example 2:**
+
+**Input:** technique1 = [10,20,30], technique2 = [5,15,25], k = 2
+
+**Output:** 60
+
+**Explanation:**
+
+We must complete at least `k = 2` tasks using `technique1`.
+
+Choosing all tasks using technique 1 yields the maximum points: `10 + 20 + 30 = 60`.
+
+**Example 3:**
+
+**Input:** technique1 = [1,2,3], technique2 = [4,5,6], k = 0
+
+**Output:** 15
+
+**Explanation:**
+
+Since `k = 0`, we are not required to choose any task using `technique1`.
+
+Choosing all tasks using technique 2 yields the maximum points: `4 + 5 + 6 = 15`.
+
+**Constraints:**
+
+* 1 <= n == technique1.length == technique2.length <= 105
+* 1 <= technique1[i], technique2[i] <= 105
+* `0 <= k <= n`
\ No newline at end of file
diff --git a/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java
new file mode 100644
index 000000000..a48cdb007
--- /dev/null
+++ b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/Solution.java
@@ -0,0 +1,60 @@
+package g3701_3800.s3768_minimum_inversion_count_in_subarrays_of_fixed_length;
+
+// #Hard #Array #Sliding_Window #Segment_Tree #Senior_Staff #Biweekly_Contest_171
+// #2026_05_08_Time_157_ms_(94.34%)_Space_125.70_MB_(100.00%)
+
+import java.util.Arrays;
+
+public class Solution {
+ public long minInversionCount(int[] nums, int k) {
+ int n = nums.length;
+ // discretization of coordinates
+ int[] sorted = nums.clone();
+ Arrays.sort(sorted);
+ for (int i = 0; i < n; i++) {
+ nums[i] = Arrays.binarySearch(sorted, nums[i]) + 1;
+ }
+ BinaryIndexedTree bit = new BinaryIndexedTree(n);
+ long invCount = 0L;
+ long ans = Long.MAX_VALUE;
+ for (int i = 0; i < n; i++) {
+ bit.add(nums[i], 1);
+ invCount += Math.min(i + 1, k) - bit.presum(nums[i]);
+ if (i < k - 1) {
+ continue;
+ }
+ ans = Math.min(ans, invCount);
+ invCount -= bit.presum(nums[i - k + 1] - 1);
+ bit.add(nums[i - k + 1], -1);
+ }
+ return ans;
+ }
+
+ private class BinaryIndexedTree {
+ private final int[] tree;
+
+ public BinaryIndexedTree(int n) {
+ tree = new int[n + 1];
+ }
+
+ public void add(int i, int val) {
+ while (i < tree.length) {
+ tree[i] += val;
+ i += lowbit(i);
+ }
+ }
+
+ public int presum(int i) {
+ int sum = 0;
+ while (i > 0) {
+ sum += tree[i];
+ i -= lowbit(i);
+ }
+ return sum;
+ }
+
+ private int lowbit(int n) {
+ return n & (-n);
+ }
+ }
+}
diff --git a/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/readme.md b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/readme.md
new file mode 100644
index 000000000..7088d2594
--- /dev/null
+++ b/src/main/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/readme.md
@@ -0,0 +1,56 @@
+3768\. Minimum Inversion Count in Subarrays of Fixed Length
+
+Hard
+
+You are given an integer array `nums` of length `n` and an integer `k`.
+
+An **inversion** is a pair of indices `(i, j)` from `nums` such that `i < j` and `nums[i] > nums[j]`.
+
+The **inversion count** of a **non-empty subarrays** is the number of inversions within it.
+
+Return the **minimum** inversion count among all **subarrays** of `nums` with length `k`.
+
+**Example 1:**
+
+**Input:** nums = [3,1,2,5,4], k = 3
+
+**Output:** 0
+
+**Explanation:**
+
+We consider all subarrays of length `k = 3` (indices below are relative to each subarray):
+
+* `[3, 1, 2]` has 2 inversions: `(0, 1)` and `(0, 2)`.
+* `[1, 2, 5]` has 0 inversions.
+* `[2, 5, 4]` has 1 inversion: `(1, 2)`.
+
+The minimum inversion count among all subarrays of length `3` is 0, achieved by subarray `[1, 2, 5]`.
+
+**Example 2:**
+
+**Input:** nums = [5,3,2,1], k = 4
+
+**Output:** 6
+
+**Explanation:**
+
+There is only one subarray of length `k = 4`: `[5, 3, 2, 1]`.
+Within this subarray, the inversions are: `(0, 1)`, `(0, 2)`, `(0, 3)`, `(1, 2)`, `(1, 3)`, and `(2, 3)`.
+Total inversions is 6, so the minimum inversion count is 6.
+
+**Example 3:**
+
+**Input:** nums = [2,1], k = 1
+
+**Output:** 0
+
+**Explanation:**
+
+All subarrays of length `k = 1` contain only one element, so no inversions are possible.
+The minimum inversion count is therefore 0.
+
+**Constraints:**
+
+* 1 <= n == nums.length <= 105
+* 1 <= nums[i] <= 109
+* `1 <= k <= n`
\ No newline at end of file
diff --git a/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/Solution.java b/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/Solution.java
new file mode 100644
index 000000000..b7b3832a9
--- /dev/null
+++ b/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/Solution.java
@@ -0,0 +1,38 @@
+package g3701_3800.s3769_sort_integers_by_binary_reflection;
+
+// #Easy #Array #Sorting #Mid_Level #Weekly_Contest_479
+// #2026_05_08_Time_5_ms_(97.23%)_Space_46.52_MB_(97.70%)
+
+import java.util.PriorityQueue;
+
+public class Solution {
+ public int[] sortByReflection(int[] nums) {
+ PriorityQueue minHeap =
+ new PriorityQueue<>(
+ (a, b) -> {
+ if (a[1] == b[1]) {
+ return Integer.compare(a[0], b[0]);
+ }
+ return Integer.compare(a[1], b[1]);
+ });
+ int[] sortedByReflection = new int[nums.length];
+ for (int num : nums) {
+ minHeap.offer(new int[] {num, reverseBinary(num)});
+ }
+ int idx = 0;
+ while (!minHeap.isEmpty()) {
+ sortedByReflection[idx++] = minHeap.poll()[0];
+ }
+ return sortedByReflection;
+ }
+
+ private int reverseBinary(int num) {
+ int reversed = 0;
+ while (num > 0) {
+ int lastBit = num & 1;
+ reversed = (reversed << 1) | lastBit;
+ num = num >> 1;
+ }
+ return reversed;
+ }
+}
diff --git a/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/readme.md b/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/readme.md
new file mode 100644
index 000000000..b93acafb7
--- /dev/null
+++ b/src/main/java/g3701_3800/s3769_sort_integers_by_binary_reflection/readme.md
@@ -0,0 +1,50 @@
+3769\. Sort Integers by Binary Reflection
+
+Easy
+
+You are given an integer array `nums`.
+
+The **binary reflection** of a **positive** integer is defined as the number obtained by reversing the order of its **binary** digits (ignoring any leading zeros) and interpreting the resulting binary number as a decimal.
+
+Sort the array in **ascending** order based on the binary reflection of each element. If two different numbers have the same binary reflection, the **smaller** original number should appear first.
+
+Return the resulting sorted array.
+
+**Example 1:**
+
+**Input:** nums = [4,5,4]
+
+**Output:** [4,4,5]
+
+**Explanation:**
+
+Binary reflections are:
+
+* 4 -> (binary) `100` -> (reversed) `001` -> 1
+* 5 -> (binary) `101` -> (reversed) `101` -> 5
+* 4 -> (binary) `100` -> (reversed) `001` -> 1
+
+Sorting by the reflected values gives `[4, 4, 5]`.
+
+**Example 2:**
+
+**Input:** nums = [3,6,5,8]
+
+**Output:** [8,3,6,5]
+
+**Explanation:**
+
+Binary reflections are:
+
+* 3 -> (binary) `11` -> (reversed) `11` -> 3
+* 6 -> (binary) `110` -> (reversed) `011` -> 3
+* 5 -> (binary) `101` -> (reversed) `101` -> 5
+* 8 -> (binary) `1000` -> (reversed) `0001` -> 1
+
+Sorting by the reflected values gives `[8, 3, 6, 5]`.
+Note that 3 and 6 have the same reflection, so we arrange them in increasing order of original value.
+
+**Constraints:**
+
+* `1 <= nums.length <= 100`
+* 1 <= nums[i] <= 109
\ No newline at end of file
diff --git a/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/Solution.java b/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/Solution.java
new file mode 100644
index 000000000..d14e8e197
--- /dev/null
+++ b/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/Solution.java
@@ -0,0 +1,29 @@
+package g3701_3800.s3770_largest_prime_from_consecutive_prime_sum;
+
+// #Medium #Array #Math #Number_Theory #Senior #Weekly_Contest_479
+// #2026_05_08_Time_1_ms_(100.00%)_Space_42.47_MB_(96.28%)
+
+public class Solution {
+ static int[] ppr = {
+ 2, 5, 17, 41, 197, 281, 7699, 8893, 22039, 24133, 25237, 28697, 32353, 37561, 38921, 43201,
+ 44683, 55837, 61027, 66463, 70241, 86453, 102001, 109147, 116533, 119069, 121631, 129419,
+ 132059, 263171, 287137, 325019, 329401, 333821, 338279, 342761, 360979, 379667, 393961,
+ 398771
+ };
+
+ public int largestPrime(int n) {
+ int i = 0;
+ int j = ppr.length - 1;
+ int r = 0;
+ while (i <= j) {
+ int m = (i + j) >> 1;
+ if (ppr[m] <= n) {
+ r = ppr[m];
+ i = m + 1;
+ } else {
+ j = m - 1;
+ }
+ }
+ return r;
+ }
+}
diff --git a/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/readme.md b/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/readme.md
new file mode 100644
index 000000000..303111e34
--- /dev/null
+++ b/src/main/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/readme.md
@@ -0,0 +1,40 @@
+3770\. Largest Prime from Consecutive Prime Sum
+
+Medium
+
+You are given an integer `n`.
+
+Return the **largest prime number** less than or equal to `n` that can be expressed as the **sum** of one or more **consecutive prime numbers** starting from 2. If no such number exists, return 0.
+
+**Example 1:**
+
+**Input:** n = 20
+
+**Output:** 17
+
+**Explanation:**
+
+The prime numbers less than or equal to `n = 20` which are consecutive prime sums are:
+
+* `2 = 2`
+
+* `5 = 2 + 3`
+
+* `17 = 2 + 3 + 5 + 7`
+
+
+The largest is 17, so it is the answer.
+
+**Example 2:**
+
+**Input:** n = 2
+
+**Output:** 2
+
+**Explanation:**
+
+The only consecutive prime sum less than or equal to 2 is 2 itself.
+
+**Constraints:**
+
+* 1 <= n <= 5 * 105
\ No newline at end of file
diff --git a/src/test/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/SolutionTest.java b/src/test/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/SolutionTest.java
new file mode 100644
index 000000000..a2a375ff3
--- /dev/null
+++ b/src/test/java/g3701_3800/s3760_maximum_substrings_with_distinct_start/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3701_3800.s3760_maximum_substrings_with_distinct_start;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void maxDistinct() {
+ assertThat(new Solution().maxDistinct("abca"), equalTo(3));
+ }
+
+ @Test
+ void maxDistinct2() {
+ assertThat(new Solution().maxDistinct("aaaa"), equalTo(1));
+ }
+
+ @Test
+ void maxDistinct3() {
+ assertThat(new Solution().maxDistinct("abcdefghijklmnopqrstuvwxyz"), equalTo(26));
+ }
+}
diff --git a/src/test/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/SolutionTest.java b/src/test/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/SolutionTest.java
new file mode 100644
index 000000000..e052f0d18
--- /dev/null
+++ b/src/test/java/g3701_3800/s3761_minimum_absolute_distance_between_mirror_pairs/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3701_3800.s3761_minimum_absolute_distance_between_mirror_pairs;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void minMirrorPairDistance() {
+ assertThat(new Solution().minMirrorPairDistance(new int[] {12, 21}), equalTo(1));
+ }
+
+ @Test
+ void minMirrorPairDistance2() {
+ assertThat(new Solution().minMirrorPairDistance(new int[] {10, 1, 100}), equalTo(1));
+ }
+
+ @Test
+ void minMirrorPairDistance3() {
+ assertThat(new Solution().minMirrorPairDistance(new int[] {12, 34, 56}), equalTo(-1));
+ }
+}
diff --git a/src/test/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/SolutionTest.java b/src/test/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/SolutionTest.java
new file mode 100644
index 000000000..bd3eaa460
--- /dev/null
+++ b/src/test/java/g3701_3800/s3762_minimum_operations_to_equalize_subarrays/SolutionTest.java
@@ -0,0 +1,26 @@
+package g3701_3800.s3762_minimum_operations_to_equalize_subarrays;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void minOperations() {
+ long[] result = new Solution().minOperations(new int[] {1, 3, 5}, 2, new int[][] {{0, 2}});
+ assertThat(result[0], equalTo(2L));
+ }
+
+ @Test
+ void minOperations2() {
+ long[] result = new Solution().minOperations(new int[] {1, 3, 5}, 2, new int[][] {{0, 1}});
+ assertThat(result[0], equalTo(1L));
+ }
+
+ @Test
+ void minOperations3() {
+ long[] result = new Solution().minOperations(new int[] {1, 2}, 2, new int[][] {{0, 1}});
+ assertThat(result[0], equalTo(-1L));
+ }
+}
diff --git a/src/test/java/g3701_3800/s3764_most_common_course_pairs/MysqlTest.java b/src/test/java/g3701_3800/s3764_most_common_course_pairs/MysqlTest.java
new file mode 100644
index 000000000..874284821
--- /dev/null
+++ b/src/test/java/g3701_3800/s3764_most_common_course_pairs/MysqlTest.java
@@ -0,0 +1,94 @@
+package g3701_3800.s3764_most_common_course_pairs;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.sql.DataSource;
+import org.junit.jupiter.api.Test;
+import org.zapodot.junit.db.annotations.EmbeddedDatabase;
+import org.zapodot.junit.db.annotations.EmbeddedDatabaseTest;
+import org.zapodot.junit.db.common.CompatibilityMode;
+
+@EmbeddedDatabaseTest(
+ compatibilityMode = CompatibilityMode.MySQL,
+ initialSqls =
+ "CREATE TABLE course_completions ("
+ + " user_id INTEGER,"
+ + " course_id INTEGER,"
+ + " course_name VARCHAR(512),"
+ + " completion_date DATE,"
+ + " course_rating INTEGER,"
+ + " PRIMARY KEY (user_id, course_id)"
+ + ");"
+ + "INSERT INTO course_completions (user_id, course_id, course_name, completion_date,"
+ + " course_rating) VALUES"
+ + "(1, 101, 'Python Basics', '2024-01-05', 5),"
+ + "(1, 102, 'SQL Fundamentals', '2024-02-10', 4),"
+ + "(1, 103, 'JavaScript', '2024-03-15', 5),"
+ + "(1, 104, 'React Basics', '2024-04-20', 4),"
+ + "(1, 105, 'Node.js', '2024-05-25', 5),"
+ + "(1, 106, 'Docker', '2024-06-30', 4),"
+ + "(2, 101, 'Python Basics', '2024-01-08', 4),"
+ + "(2, 104, 'React Basics', '2024-02-14', 5),"
+ + "(2, 105, 'Node.js', '2024-03-20', 4),"
+ + "(2, 106, 'Docker', '2024-04-25', 5),"
+ + "(2, 107, 'AWS Fundamentals', '2024-05-30', 4),"
+ + "(3, 101, 'Python Basics', '2024-01-10', 3),"
+ + "(3, 102, 'SQL Fundamentals', '2024-02-12', 3),"
+ + "(3, 103, 'JavaScript', '2024-03-18', 3),"
+ + "(3, 104, 'React Basics', '2024-04-22', 2),"
+ + "(3, 105, 'Node.js', '2024-05-28', 3),"
+ + "(4, 101, 'Python Basics', '2024-01-12', 5),"
+ + "(4, 108, 'Data Science', '2024-02-16', 5),"
+ + "(4, 109, 'Machine Learning', '2024-03-22', 5);")
+class MysqlTest {
+ @Test
+ void testScript(@EmbeddedDatabase DataSource dataSource)
+ throws SQLException, FileNotFoundException {
+ try (final Connection connection = dataSource.getConnection()) {
+ try (final Statement statement = connection.createStatement();
+ final ResultSet resultSet =
+ statement.executeQuery(
+ new BufferedReader(
+ new FileReader(
+ "src/main/java/g3701_3800/"
+ + "s3764_most_common_course_pairs/"
+ + "script.sql"))
+ .lines()
+ .collect(Collectors.joining("\n"))
+ .replaceAll("#.*?\\r?\\n", ""))) {
+ List actualRows = new ArrayList<>();
+ while (resultSet.next()) {
+ actualRows.add(
+ resultSet.getString(1)
+ + "|"
+ + resultSet.getString(2)
+ + "|"
+ + resultSet.getString(3));
+ }
+
+ List expectedRows =
+ Arrays.asList(
+ "Node.js|Docker|2",
+ "React Basics|Node.js|2",
+ "Docker|AWS Fundamentals|1",
+ "JavaScript|React Basics|1",
+ "Python Basics|React Basics|1",
+ "Python Basics|SQL Fundamentals|1",
+ "SQL Fundamentals|JavaScript|1");
+ assertThat(actualRows, equalTo(expectedRows));
+ }
+ }
+ }
+}
diff --git a/src/test/java/g3701_3800/s3765_complete_prime_number/SolutionTest.java b/src/test/java/g3701_3800/s3765_complete_prime_number/SolutionTest.java
new file mode 100644
index 000000000..b1e3478a0
--- /dev/null
+++ b/src/test/java/g3701_3800/s3765_complete_prime_number/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3701_3800.s3765_complete_prime_number;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void completePrime() {
+ assertThat(new Solution().completePrime(239), equalTo(false));
+ }
+
+ @Test
+ void completePrime2() {
+ assertThat(new Solution().completePrime(21), equalTo(false));
+ }
+
+ @Test
+ void completePrime3() {
+ assertThat(new Solution().completePrime(2), equalTo(true));
+ }
+}
diff --git a/src/test/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/SolutionTest.java b/src/test/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/SolutionTest.java
new file mode 100644
index 000000000..e0113c123
--- /dev/null
+++ b/src/test/java/g3701_3800/s3766_minimum_operations_to_make_binary_palindrome/SolutionTest.java
@@ -0,0 +1,31 @@
+package g3701_3800.s3766_minimum_operations_to_make_binary_palindrome;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void minOperations() {
+ int[] result = new Solution().minOperations(new int[] {5, 6, 7});
+ assertThat(result[0], equalTo(0));
+ assertThat(result[1], equalTo(1));
+ assertThat(result[2], equalTo(0));
+ }
+
+ @Test
+ void minOperations2() {
+ int[] result = new Solution().minOperations(new int[] {10});
+ assertThat(result[0], equalTo(1));
+ }
+
+ @Test
+ void minOperations3() {
+ int[] result = new Solution().minOperations(new int[] {1, 2, 3, 4});
+ assertThat(result[0], equalTo(0));
+ assertThat(result[1], equalTo(1));
+ assertThat(result[2], equalTo(0));
+ assertThat(result[3], equalTo(1));
+ }
+}
diff --git a/src/test/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/SolutionTest.java b/src/test/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/SolutionTest.java
new file mode 100644
index 000000000..fe39fda45
--- /dev/null
+++ b/src/test/java/g3701_3800/s3767_maximize_points_after_choosing_k_tasks/SolutionTest.java
@@ -0,0 +1,62 @@
+package g3701_3800.s3767_maximize_points_after_choosing_k_tasks;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void maxPoints() {
+ assertThat(
+ new Solution().maxPoints(new int[] {5, 1, 3}, new int[] {4, 10, 2}, 1),
+ equalTo(18L));
+ }
+
+ @Test
+ void maxPoints2() {
+ assertThat(new Solution().maxPoints(new int[] {1, 2}, new int[] {3, 4}, 0), equalTo(7L));
+ }
+
+ @Test
+ void maxPoints3() {
+ assertThat(
+ new Solution().maxPoints(new int[] {7, 2, 5}, new int[] {1, 8, 4}, 3),
+ equalTo(14L));
+ }
+
+ @Test
+ void maxPoints4() {
+ assertThat(
+ new Solution().maxPoints(new int[] {5, 4, 3}, new int[] {3, 4, 1}, 3),
+ equalTo(12L));
+ }
+
+ @Test
+ void maxPoints5() {
+ assertThat(
+ new Solution().maxPoints(new int[] {1, 2, 3}, new int[] {5, 5, 1}, 1),
+ equalTo(13L));
+ }
+
+ @Test
+ void maxPoints6() {
+ assertThat(
+ new Solution().maxPoints(new int[] {1, 1, 1, 1}, new int[] {3, 4, 2, 6}, 2),
+ equalTo(12L));
+ }
+
+ @Test
+ void maxPoints7() {
+ assertThat(
+ new Solution().maxPoints(new int[] {1, 1, 1, 1}, new int[] {6, 5, 4, 0}, 2),
+ equalTo(13L));
+ }
+
+ @Test
+ void maxPoints8() {
+ assertThat(
+ new Solution().maxPoints(new int[] {7, 8, 9}, new int[] {100, 100, 100}, 3),
+ equalTo(24L));
+ }
+}
diff --git a/src/test/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/SolutionTest.java b/src/test/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/SolutionTest.java
new file mode 100644
index 000000000..60ca5c1e0
--- /dev/null
+++ b/src/test/java/g3701_3800/s3768_minimum_inversion_count_in_subarrays_of_fixed_length/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3701_3800.s3768_minimum_inversion_count_in_subarrays_of_fixed_length;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void minInversionCount() {
+ assertThat(new Solution().minInversionCount(new int[] {3, 1, 2}, 2), equalTo(0L));
+ }
+
+ @Test
+ void minInversionCount2() {
+ assertThat(new Solution().minInversionCount(new int[] {3, 2, 1}, 3), equalTo(3L));
+ }
+
+ @Test
+ void minInversionCount3() {
+ assertThat(new Solution().minInversionCount(new int[] {1, 2, 3, 4}, 2), equalTo(0L));
+ }
+}
diff --git a/src/test/java/g3701_3800/s3769_sort_integers_by_binary_reflection/SolutionTest.java b/src/test/java/g3701_3800/s3769_sort_integers_by_binary_reflection/SolutionTest.java
new file mode 100644
index 000000000..88d8e9ac5
--- /dev/null
+++ b/src/test/java/g3701_3800/s3769_sort_integers_by_binary_reflection/SolutionTest.java
@@ -0,0 +1,31 @@
+package g3701_3800.s3769_sort_integers_by_binary_reflection;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void sortByReflection() {
+ int[] result = new Solution().sortByReflection(new int[] {1, 2, 3});
+ assertThat(result[0], equalTo(1));
+ assertThat(result[1], equalTo(2));
+ assertThat(result[2], equalTo(3));
+ }
+
+ @Test
+ void sortByReflection2() {
+ int[] result = new Solution().sortByReflection(new int[] {0, 1, 2});
+ assertThat(result[0], equalTo(0));
+ assertThat(result[1], equalTo(1));
+ assertThat(result[2], equalTo(2));
+ }
+
+ @Test
+ void sortByReflection3() {
+ int[] result = new Solution().sortByReflection(new int[] {6, 9});
+ assertThat(result[0], equalTo(6));
+ assertThat(result[1], equalTo(9));
+ }
+}
diff --git a/src/test/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/SolutionTest.java b/src/test/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/SolutionTest.java
new file mode 100644
index 000000000..be82bfa3a
--- /dev/null
+++ b/src/test/java/g3701_3800/s3770_largest_prime_from_consecutive_prime_sum/SolutionTest.java
@@ -0,0 +1,23 @@
+package g3701_3800.s3770_largest_prime_from_consecutive_prime_sum;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class SolutionTest {
+ @Test
+ void largestPrime() {
+ assertThat(new Solution().largestPrime(100), equalTo(41));
+ }
+
+ @Test
+ void largestPrime2() {
+ assertThat(new Solution().largestPrime(2), equalTo(2));
+ }
+
+ @Test
+ void largestPrime3() {
+ assertThat(new Solution().largestPrime(1), equalTo(0));
+ }
+}