Блог пользователя happywobbuffet

Автор happywobbuffet, история, 10 месяцев назад, По-английски

Hello! I was solving this Leetcode problem yesterday.

I'll rewrite the problem statement once again for convenience

Problem Statement
Examples
Constraints

I would suggest you to solve (in your head or code) this before going further

My Submission (C++)

Now, lets say I have $$$q$$$ Queries of Type:

  • $$$1$$$ $$$L$$$ $$$R$$$ $$$k$$$ where-
  • $$$L$$$ and $$$R$$$ represent the left and rite endpoints of a subarray in $$$nums$$$ inclusive.
  • $$$k$$$ represents the number of operations that can be used to make the entire subarray equal.

For every query, we need to return $$$true$$$ or $$$false$$$ if we are able to make the entire subarray equal.

Here are my observations and approach:

O(n + qlogn) Approach

Not completely positive of my approach so would like to hear any corrections, improvements or suggestions.

So far, we've only seen static/immutable arrays. Lets say I also have a query of Type 2, where

  • $$$2$$$ $$$p$$$ : nums[p] *= -1. (flipping the value at index $$$p$$$).

In this case, how do i device an efficient solution when considering queries of both types? Any Ideas?

Wobbuffet

  • Проголосовать: нравится
  • +15
  • Проголосовать: не нравится

»
10 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by happywobbuffet (previous revision, new revision, compare).

»
10 месяцев назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

Some observations:

  1. We should handle the two cases ($$$1$$$ and $$$-1$$$) separately.
  2. For one case, we only care the indices of the numbers. For example, if the index array of all $$$1$$$ is $$$[1, 2, 3, 5]$$$, then the total number of operations to turn them to $$$-1$$$ would be $$$3 = - 1 + 2 - 3 + 5$$$. Apparently this is an alternating sum on the index array.
  3. Then with preprocessing of all indices of $$$1$$$ and $$$-1$$$, we can answer each type 1 query in $$$O(1)$$$.
  4. For type 2 query, we are basically inserting/deleting numbers to/from the index array, and the sign of all subsequent numbers in the index array will change for the alternating sum. Naively, this results in $$$O(n)$$$ complexity to process each query. Deepseek suggests we can use SegmentTree or Balanced Binary Search Tree to optimize it and achieve $$$O(logn)$$$ complexity.
»
10 месяцев назад, скрыть # |
 
Проголосовать: нравится +9 Проголосовать: не нравится

You can view this problem as an instance of Gaussian elimination over $$$GF(2)$$$ (in other words, XOR). First of all, change $$$1 \rightarrow 1$$$ and $$$-1 \rightarrow 0$$$. Now you have a binary string.

For example, let's say initially you have the string $$$abcd$$$. Denote an operation at the $$$i$$$-th index as $$$p_i$$$. Note that operating on an index twice does nothing. So in essence, we have the following equations if we want to make everything equal to $$$0$$$:

$$$ \begin{align*} a + p_0 &\equiv 0 \pmod{2} \\ b + p_0 + p_1 &\equiv 0 \pmod{2} \\ c + p_1 + p_2 &\equiv 0 \pmod{2} \\ d + p_2 &\equiv 0 \pmod{2} \end{align*} $$$

We can further write

$$$ \begin{align*} p_0 &\equiv a \pmod{2} \\ p_0 + p_1 &\equiv b \pmod{2} \\ p_1 + p_2 &\equiv c \pmod{2} \\ p_2 &\equiv d \pmod{2} \end{align*} $$$

Now we can eliminate to get

$$$ \begin{align*} p_0 &\equiv a \pmod{2} \\ p_1 &\equiv a + b \pmod{2} \\ p_2 &\equiv a + b + c \pmod{2} \\ 0 &\equiv a + b + c + d \pmod{2} \end{align*} $$$

This means that, we need to take the prefix XOR, check that the XOR of the whole array is $$$0$$$, and then count the number of $$$1$$$-s in the prefix XOR array and check if it is $$$\leq k$$$.

This isn't the only possibility of course, you can also make everything equal to $$$1$$$. To handle that, you can just flip every bit and run the same procedure. So we'll not talk about this case, but remember to handle it (just make another array and run the procedure on both arrays and check if either one works).

So now you have an $$$O(n + q)$$$ solution to your first variant: You know how to count the number of $$$1$$$-s in the prefix XOR of a subarray $$$[L, R]$$$: maintain a prefix sum of how many $$$1$$$-s are there in the prefix XOR array, and if $$$\text{prefix_XOR}[L-1]$$$ is $$$1$$$, you have $$$R-L+1-\text{count}_1(L, R)$$$ number of $$$1$$$-s (you get the idea). Also remember to check the whole subarray XOR is $$$0$$$.

To solve your variant with type $$$2$$$ updates, I think you can see we need a Fenwick tree now.

  • »
    »
    10 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    very nice approach. took me a while to understand it!

    Accepted LC Submission Code (C++)

    I'm still very new to the realm of Fenwick/Segment Tree like Data Structures, could you help with some hints?