Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package g3801_3900.s3841_palindromic_path_queries_in_a_tree;

// #Hard #Array #String #Tree #Bit_Manipulation #Divide_and_Conquer #Segment_Tree
// #Biweekly_Contest_176 #Principal #Depth_First_Search
// #2026_07_22_Time_65_ms_(100.00%)_Space_185.61_MB_(96.67%)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Solution {
private int[] head;
private int[] to;
private int[] next;

private int[][] lift;
private int[] first;
private int[] last;
private int[] depth;
private int time = 0;
private int maxPower;

public List<Boolean> palindromePath(int n, int[][] edges, String s, String[] queries) {
this.first = new int[n];
this.last = new int[n];
this.maxPower = 31 - Integer.numberOfLeadingZeros(n);
this.depth = new int[n];
this.lift = new int[maxPower + 1][n];
int m = edges.length;
this.head = new int[n];
this.to = new int[m << 1];
this.next = new int[m << 1];
Arrays.fill(head, -1);
for (int i = 0; i < m; i++) {
int a = edges[i][0];
int b = edges[i][1];
to[i << 1] = b;
next[i << 1] = head[a];
head[a] = i << 1;
to[i << 1 | 1] = a;
next[i << 1 | 1] = head[b];
head[b] = i << 1 | 1;
}
dfs(0, -1);
BIT bit = new BIT(n + 1);
char[] arr = s.toCharArray();
for (int i = 0; i < n; i++) {
bit.update(first[i], 1 << arr[i] - 'a');
bit.update(last[i] + 1, 1 << arr[i] - 'a');
}
ArrayList<Boolean> list = new ArrayList<>(queries.length);
for (String query : queries) {
if (query.charAt(0) == 'u') {
int i = Integer.parseInt(query.substring(7, query.length() - 2));
char c = query.charAt(query.length() - 1);
if (c == arr[i]) {
continue;
}
int filter = 1 << arr[i] - 'a' | 1 << c - 'a';
bit.update(first[i], filter);
arr[i] = c;
bit.update(last[i] + 1, filter);
} else {
int i1 = query.indexOf(' ');
int i2 = query.lastIndexOf(' ');
int a = Integer.parseInt(query.substring(i1 + 1, i2));
int b = Integer.parseInt(query.substring(i2 + 1));
int r = bit.query(first[a]) ^ bit.query(first[b]) ^ 1 << arr[lca(a, b)] - 'a';
list.add((r & r - 1) == 0);
}
}
return list;
}

private int lca(int a, int b) {
if (depth[a] > depth[b]) {
int temp = a;
a = b;
b = temp;
}
if (first[a] <= first[b] && last[a] >= last[b]) {
return a;
}
int diff = depth[b] - depth[a];
for (int i = maxPower; diff != 0; --i) {
if (diff >= 1 << i) {
b = lift[i][b];
diff -= 1 << i;
}
}
if (a == b) {
return a;
}
for (int i = maxPower; i >= 0; --i) {
if (lift[i][a] != lift[i][b]) {
a = lift[i][a];
b = lift[i][b];
}
}
return lift[0][a];
}

private void dfs(int index, int prev) {
first[index] = ++time;
for (int x = head[index]; x != -1; x = next[x]) {
int nextIndex = to[x];
if (nextIndex == prev) {
continue;
}
depth[nextIndex] = depth[index] + 1;
lift[0][nextIndex] = index;
for (int i = 1; (1 << i) < depth[nextIndex]; i++) {
lift[i][nextIndex] = lift[i - 1][lift[i - 1][nextIndex]];
}
dfs(nextIndex, index);
}
last[index] = time;
}

private static class BIT {
private final int[] ints;
private final int n;

BIT(int n) {
this.n = n;
this.ints = new int[n + 1];
}

public void update(int index, int val) {
for (int i = index + 1; i <= n; i += i & -i) {
ints[i] ^= val;
}
}

public int query(int index) {
int ans = 0;
for (int i = index + 1; i > 0; i -= i & -i) {
ans ^= ints[i];
}
return ans;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
3841\. Palindromic Path Queries in a Tree

Hard

You are given an undirected tree with `n` nodes labeled 0 to `n - 1`. This is represented by a 2D array `edges` of length `n - 1`, where <code>edges[i] = [u<sub>i</sub>, v<sub>i</sub>]</code> indicates an undirected edge between nodes <code>u<sub>i</sub></code> and <code>v<sub>i</sub></code>.

You are also given a string `s` of length `n` consisting of lowercase English letters, where `s[i]` represents the character assigned to node `i`.

You are also given a string array `queries`, where each `queries[i]` is either:

* <code>"update u<sub>i</sub> c"</code>: Change the character at node <code>u<sub>i</sub></code> to `c`. Formally, update <code>s[u<sub>i</sub>] = c</code>.
* <code>"query u<sub>i</sub> v<sub>i</sub>"</code>: Determine whether the string formed by the characters on the **unique** path from <code>u<sub>i</sub></code> to <code>v<sub>i</sub></code> (inclusive) can be **rearranged** into a **palindrome**.

Return a boolean array `answer`, where `answer[j]` is `true` if the <code>j<sup>th</sup></code> query of type <code>"query u<sub>i</sub> v<sub>i</sub>"</code> can be rearranged into a **palindrome**, and `false` otherwise.

**Example 1:**

**Input:** n = 3, edges = [[0,1],[1,2]], s = "aac", queries = ["query 0 2","update 1 b","query 0 2"]

**Output:** [true,false]

**Explanation:**

* `"query 0 2"`: Path `0 → 1 → 2` gives `"aac"`, which can be rearranged to form `"aca"`, a palindrome. Thus, `answer[0] = true`.
* `"update 1 b"`: Update node 1 to `'b'`, now `s = "abc"`.
* `"query 0 2"`: Path characters are `"abc"`, which cannot be rearranged to form a palindrome. Thus, `answer[1] = false`.

Thus, `answer = [true, false]`.

**Example 2:**

**Input:** n = 4, edges = [[0,1],[0,2],[0,3]], s = "abca", queries = ["query 1 2","update 0 b","query 2 3","update 3 a","query 1 3"]

**Output:** [false,false,true]

**Explanation:**

* `"query 1 2"`: Path `1 → 0 → 2` gives `"bac"`, which cannot be rearranged to form a palindrome. Thus, `answer[0] = false`.
* `"update 0 b"`: Update node 0 to `'b'`, now `s = "bbca"`.
* `"query 2 3"`: Path `2 → 0 → 3` gives `"cba"`, which cannot be rearranged to form a palindrome. Thus, `answer[1] = false`.
* `"update 3 a"`: Update node 3 to `'a'`, `s = "bbca"`.
* `"query 1 3"`: Path `1 → 0 → 3` gives `"bba"`, which can be rearranged to form `"bab"`, a palindrome. Thus, `answer[2] = true`.

Thus, `answer = [false, false, true]`.

**Constraints:**

* <code>1 <= n == s.length <= 5 * 10<sup>4</sup></code>
* `edges.length == n - 1`
* <code>edges[i] = [u<sub>i</sub>, v<sub>i</sub>]</code>
* <code>0 <= u<sub>i</sub>, v<sub>i</sub> <= n - 1</code>
* `s` consists of lowercase English letters.
* The input is generated such that `edges` represents a valid tree.
* <code>1 <= queries.length <= 5 * 10<sup>4</sup></code>
* <code>queries[i] = "update u<sub>i</sub> c"</code> or
* <code>queries[i] = "query u<sub>i</sub> v<sub>i</sub>"</code>
* <code>0 <= u<sub>i</sub>, v<sub>i</sub> <= n - 1</code>
* `c` is a lowercase English letter.
23 changes: 23 additions & 0 deletions src/main/java/g3801_3900/s3842_toggle_light_bulbs/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package g3801_3900.s3842_toggle_light_bulbs;

// #Easy #Array #Hash_Table #Sorting #Simulation #Mid_Level #Weekly_Contest_489
// #2026_07_22_Time_2_ms_(99.86%)_Space_46.70_MB_(58.12%)

import java.util.ArrayList;
import java.util.List;

public class Solution {
public List<Integer> toggleLightBulbs(List<Integer> bulbs) {
boolean[] on = new boolean[101];
for (int b : bulbs) {
on[b] = !on[b];
}
List<Integer> ans = new ArrayList<>();
for (int i = 1; i < 101; ++i) {
if (on[i]) {
ans.add(i);
}
}
return ans;
}
}
45 changes: 45 additions & 0 deletions src/main/java/g3801_3900/s3842_toggle_light_bulbs/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
3842\. Toggle Light Bulbs

Easy

You are given an array `bulbs` of integers between 1 and 100.

There are 100 light bulbs numbered from 1 to 100. All of them are switched off initially.

For each element `bulbs[i]` in the array `bulbs`:

* If the <code>bulbs[i]<sup>th</sup></code> light bulb is currently off, switch it on.
* Otherwise, switch it off.

Return the list of integers denoting the light bulbs that are on in the end, **sorted** in **ascending** order. If no bulb is on, return an empty list.

**Example 1:**

**Input:** bulbs = [10,30,20,10]

**Output:** [20,30]

**Explanation:**

* The <code>bulbs[0] = 10<sup>th</sup></code> light bulb is currently off. We switch it on.
* The <code>bulbs[1] = 30<sup>th</sup></code> light bulb is currently off. We switch it on.
* The <code>bulbs[2] = 20<sup>th</sup></code> light bulb is currently off. We switch it on.
* The <code>bulbs[3] = 10<sup>th</sup></code> light bulb is currently on. We switch it off.
* In the end, the 20<sup>th</sup> and the 30<sup>th</sup> light bulbs are on.

**Example 2:**

**Input:** bulbs = [100,100]

**Output:** []

**Explanation:**

* The <code>bulbs[0] = 100<sup>th</sup></code> light bulb is currently off. We switch it on.
* The <code>bulbs[1] = 100<sup>th</sup></code> light bulb is currently on. We switch it off.
* In the end, no light bulb is on.

**Constraints:**

* `1 <= bulbs.length <= 100`
* `1 <= bulbs[i] <= 100`
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package g3801_3900.s3843_first_element_with_unique_frequency;

// #Medium #Array #Hash_Table #Counting #Senior #Weekly_Contest_489
// #2026_07_22_Time_96_ms_(93.48%)_Space_213.96_MB_(84.60%)

import java.util.HashMap;
import java.util.Map;

public class Solution {
public int firstUniqueFreq(int[] nums) {
Map<Integer, Integer> c1 = new HashMap<>();
for (int a : nums) {
c1.put(a, c1.getOrDefault(a, 0) + 1);
}
Map<Integer, Integer> c2 = new HashMap<>();
for (int f : c1.values()) {
c2.put(f, c2.getOrDefault(f, 0) + 1);
}
for (int a : nums) {
if (c2.get(c1.get(a)) == 1) {
return a;
}
}
return -1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
3843\. First Element with Unique Frequency

Medium

You are given an integer array `nums`.

Return an integer denoting the **first** element (scanning from left to right) in `nums` whose **frequency** is **unique**. That is, no other integer appears the same number of times in `nums`. If there is no such element, return -1.

**Example 1:**

**Input:** nums = [20,10,30,30]

**Output:** 30

**Explanation:**

* 20 appears once.
* 10 appears once.
* 30 appears twice.
* The frequency of 30 is unique because no other integer appears exactly twice.

**Example 2:**

**Input:** nums = [20,20,10,30,30,30]

**Output:** 20

**Explanation:**

* 20 appears twice.
* 10 appears once.
* 30 appears 3 times.
* The frequency of 20, 10, and 30 are unique. The first element that has unique frequency is 20.

**Example 3:**

**Input:** nums = [10,10,20,20]

**Output:** \-1

**Explanation:**

* 10 appears twice.
* 20 appears twice.
* No element has a unique frequency.

**Constraints:**

* <code>1 <= nums.length <= 10<sup>5</sup></code>
* <code>1 <= nums[i] <= 10<sup>5</sup></code>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package g3801_3900.s3844_longest_almost_palindromic_substring;

// #Medium #String #Dynamic_Programming #Two_Pointers #Staff #Weekly_Contest_489
// #2026_07_22_Time_10_ms_(99.05%)_Space_44.41_MB_(61.90%)

public class Solution {
private int n;
private char[] s;

public int almostPalindromic(String str) {
s = str.toCharArray();
n = s.length;
int ans = 0;
for (int i = 0; i < n; i++) {
ans = Math.max(ans, f(i, i));
ans = Math.max(ans, f(i, i + 1));
}
return ans;
}

private int f(int l, int r) {
while (l >= 0 && r < n && s[l] == s[r]) {
l--;
r++;
}
int l1 = l - 1;
int r1 = r;
int l2 = l;
int r2 = r + 1;
while (l1 >= 0 && r1 < n && s[l1] == s[r1]) {
l1--;
r1++;
}
while (l2 >= 0 && r2 < n && s[l2] == s[r2]) {
l2--;
r2++;
}
return Math.clamp(Math.max(r1 - l1 - 1, r2 - l2 - 1), 0, n);
}
}
Loading
Loading