You are given an array of n integers. Your task is to calculate the bitwise or of each window of k elements, from left to right. In this problem the input data is large and it is created using a generator. Input The first line contains two integers n and k: the number of elements and the size of the window. The next line contains four integers x, a, b and c: the input generator parameters. The input is generated as follows:
how to solve this efficiently i got tle when i try to solve n*31








Hint: Double Deque or Four Stacks (Double Stack trick to work as a deque).
can you elaborate?
Check this
Not sure if this is the intended solution but optimizing the loop for counting bits works. https://cses.fi/paste/e1dabeef32aa00fbc4cc83/
First of all, you need to construct the array $$$a$$$ from the provided generator.
After that, you split $$$a$$$ into several blocks of length $$$k$$$ with the length of the last one being at most $$$k$$$ (since $$$n \equiv 0$$$ $$$(mod$$$ $$$k)$$$ doesn't always hold), then compute the prefix and suffix OR of each of these blocks. For better understanding, here is an illustration for $$$n = 8, k = 3$$$ (I know I'm talented at drawing <(")).
Ultimately, the answer for a window $$$[i-k+1, i]$$$ is basically just $$$pre_i$$$ $$$|$$$ $$$suf_{i-k+1}$$$. For example, the OR sum of the window $$$[3, 5]$$$ is $$$pre_5$$$ $$$|$$$ $$$suf_3$$$ which is equal to $$$a_3$$$ $$$|$$$ $$$a_4$$$ $$$|$$$ $$$a_5$$$.
The resulting complexity is $$$O(n)$$$ for both time and memory.
Loved the idea, first time I’ve come across this kind of trick!
Attaching the Accepted C++ code for the above approach.
I initially tried a simpler implementation using a 2D vector to store prefix and suffix arrays for each segment, but that gave a
RUNTIME ERRORdue to overhead—especially whenk = 1, leading to around1e7vectors being created. So, I optimized the space by reusing 1D vectors curSuff and nxtPref during segment iteration. Also Attaching that Code.There is a minor initialization bug in the smaller code where "s[n — 1] = x" is not true always, thanks for sharing the code btw!
Wow, how did you come up with this?
Thanks for sharing such a nice solution. Here is my C++ code :-)
amazing solution bro
The same concept is used in another CSES Range Query problem which asks to find the maximum subarray sum in a given range [l...r]. When merging two childs one of the best segment (segment with the maximum subarray sum) could lie partially in the left child and right child and it is always possible to make that segment with some suffix of left child and prefix of right child ! So we store prefix, suffix sum max of each segment (and also another stuff the ans) in each child and get the answer by quering...Same concept used here!
We can say that main logic comes from the observation that range of size k cannot lie in more than 2 different k size segments.
Functions like min, max, OR, AND follows Idempotent and associative property therefore they are Overlapping-friendly Operation.
This trick can also be seen as the specialization of sparse table for fixed range.
True
Appreciated man! way too clean and way too brilliant solution!!
Literally too orz
I drew this while implementing, just posting it here for reference
Good observation
Alternative solution is observe that once bit is seen it will be on for k next windows, so just track off time for each bit and reconstruct or.
Just wrote a blog on this: Sliding Window: Handling Non-Invertible operators
well i did get ac with n*30 lol, probably because the constant factor was really good https://cses.fi/paste/a871c74160e6983ec5e9d5/
Can't we store the sum of bitcounts a window in a count array and update the or of the window?
Soution with two stacks. Easy to understand and accepted AC. The idea is to use two stacks one for storing bitwise or of first k elements and the other is to store bitwise or of the same elements in the reverse order so we get bitwise or in reverse order. C++ code Link. https://cses.fi/paste/a0140c746968381fe1ba9b/
Total overkill: I solved it with a segment tree of OR
not sure if this is a foolish solution but im pretty sure you could just store the count of each bit and get n that way