iez's blog

By iez, history, 10 months ago, In English

You have an array of n numbers and an integer x, find the biggest subarray so that its Product is not dividable to x and n is up to 1e5

I also have a similar question for the biggest array so that their sum is not dividable to x

  • Vote: I like it
  • +6
  • Vote: I do not like it

»
10 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

If I am not wrong both can be solved using slight modifications to the Kadane's Algorithm

»
10 months ago, hide # |
Rev. 2  
Vote: I like it 0 Vote: I do not like it

Assuming that you mean, that we have to maximize the length of subarray such that it's sum is not divisible by $$$x$$$. Here is an approach I thought of for your second problem.

We consider the entire array, and if the sum is divisible by $$$x$$$, then search from both start and the end to find the first number that is not a multiple of $$$x$$$, choose to remove elements from the side which minimizes the length of the array the least.

For example consider, $$$x = 10$$$ and the array to be $$$A = [10, 20, 34, 55, 49, 32, 30]$$$. We first choose the entire array, then we get the sum to be $$$230$$$, now we see that it is divisible by $$$x$$$ so we search from the start and from the end for the element that is not divisible by $$$x$$$. So, from the start the third element $$$34$$$ is such an element, and from the end the second element from last that is $$$32$$$ is one such element. Since, if we remove the prefix, we will end up decreasing the length by 3 and if we remove suffix we will reduce the length by 2. So, we'll prefer suffix (since it minimizes the length by the least).

I cannot prove that this works, but I think it should, counter examples are always appreciated.

  • »
    »
    10 months ago, hide # ^ |
    Rev. 2  
    Vote: I like it +3 Vote: I do not like it

    Yes i had a similar idea but i didn't pay attention that it had to be a multiple of x instead of x it self, rookie mistake, thanks

  • »
    »
    10 months ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    This could be a proof:

    When the sum of the complete array is not divisible by x, we obviously consider that to be the solution.

    When it is, i.e., sum % x == 0:

    If sum % x == 0 and any integer k in the array satisfies k % x != 0, then: (sum — k) % x != 0

    Because: (sum — k) % x = (sum % x — k % x + x) % x
    And since sum % x == 0 and k % x != 0, the result is non-zero.

    Thus, if there are two or more such elements, we compare the first to appear from the front and the back.
    If there is only one, we take that and all elements either to its left or right — whichever is larger in size.

    A very neat approach!

»
10 months ago, hide # |
Rev. 2  
Vote: I like it 0 Vote: I do not like it
  • Another approach to problem 2 can be like->

We create prefix sum of array in such a manner:

prefixsum[i] = ( prefixsum[i-1] + a[i] ) % x

Hence, the prefix_sum array would have values in the range [0,x-1].

Now, we iterate on the prefix_sum array and if we are currently at index i, and if we want to consider maximum length subarray ending at i and starting at index j+1 then we would need to find an index (j<i) such that

prefixsum[j] != prefixsum[i]

which would guarantee that prefixsum[i]-prefixsum[j] is not a multiple of x and hence the subarray sum from index j+1 to i is not divisible by x.

So, to find j we can the following logic:

  1. If prefixsum[i] != 0, then j+1 = 0 hence max length subarray would be from 0 to i.

  2. If prefixsum[i] = 0, then we just need the least index such that prefixsum[j] != 0 that can be easily pre-calculated.

»
10 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

bro why you use in the last div 3 round in problems D scanf & printf instead of use cin & cout like in other problems

»
10 months ago, hide # |
 
Vote: I like it +3 Vote: I do not like it

define dp[i] as the length of the longest subarray ending at index i.

keep a variable div which stores the product of some factors of x taken from the current subarray. The took array tracks which factor was taken from each position.

For each element, we pick a factor of x that divides it, update div, and store that factor in took[i].

If div becomes divisible by x, we move the left end (j) forward and remove factors until div is no longer divisible by x.

Then, dp[i] = i - j + 1. After checking all positions, the maximum value in dp is our answer.

Code
  • »
    »
    10 months ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    Thank you very much, it was a very nice implementation