I came up with this problem recently but haven't been able to find an efficient approach. Since it's a self-created problem, I don't have official test cases.
Problem Statement
There is a sequence a of n integers. Process q queries given in order. For q-th query, you are given integers l, r (1 <= l <= r <= n) and a integer x.Perform the following in order: Add x for each of a[l], a[l + 1],.., a[r]. Let m = r - l + 1, and b = (b[1], b[2],.., b[m]) = (a[l], a[l + 1],.., a[r]). For array b you need to perform m — 1 operations. For each operation, select two elements x, y from the array, delete them and add elements x + y to the array with a cost of x + y, find the smallest total cost modulo 1e9 + 7. (n <= 1e5, q <= 1e5, |a[i]| <= 1e9)
I can't think of a specific time limit for this problem either, but can you find the quickest way to solve it?
Update : The addition of x to the values from position l to r in the i-th query will apply to all queries from i + 1 onwards, meaning that after query i, array a becomes a = (a[1], a[2], ..., a[l] + x, a[l + 1] + x, a[r] + x, ..., a[n])
Update 2 : Sorry everyone, I mixed things up a bit while explaining my idea. I've just updated the prompt.








Auto comment: topic has been updated by AllForCode (previous revision, new revision, compare).
Auto comment: topic has been updated by AllForCode (previous revision, new revision, compare).
Well, I guess this is lazy segment tree. Please correct me if I'm wrong. Edit: Nevermind, I think I misunderstood the problem.
It is, if
sortdidn't exist. Sorting makes the problem way harder, I could only thought of when there're no updates, then one can use Mo's algorithm to get a time complexity of $$$O(n\sqrt{n}\log(n))$$$.But the sorting part is the most important part of this problem. I wrote the sort this way to simplify the operation. In fact, if I needed to explain it in words, for array b you need to perform m — 1 operations. For each operation, select two elements x, y from the array, delete them and add elements x + y to the array with a cost of x + y, find the smallest total cost modulo 1e9 + 7. After analysis, it is essentially sorting array b and giving ((m — 1) * b[1] + (m — 1) * b[2] + .. + b[m]) % (1e9 + 7)
If I understand correctly, it is not. For example, let $$$m = 4$$$ and $$$b[1] = b[2] = b[3] = b[4] = 1$$$. You can select $$$1$$$ and $$$1$$$ twice, each time for a cost of $$$2$$$, and then select $$$2$$$ and $$$2$$$ at the end for a cost of $$$4$$$. The total cost is $$$8$$$, but your formula gives $$$9$$$.
The optimal way to do this is well-studied and is known as Huffman's algorithm. It is not just a simple sort. I am pretty sure it is hard to compute this on a segment faster than by simply simulating the process, even without range increments.
Oh, sorry, thank you for pointing that out. I will correct the problem statement.
So there's no way to optimize this beyond simple simulation? If i were to do it, here’s my approach: I’d push all elements from l to r into a min-priority queue. Starting with Total_Cost = 0, I’d greedily extract the two smallest elements, x and y, then insert their sum x + y back into the queue and update Total_Cost += x + y. After repeating this m — 1 times, the Total_Cost would be the final answer. Does this simulation approach sound correct to you?
Below is a solution to a different problem. I thought the sorted array was written back over the original values. I also missed the range addition.
Use square-root decomposition on the array. For each block, store this data structure. To sort a range, merge the data structures of all affected blocks into one, then split it back into blocks. The complexity is $$$\Theta(q \sqrt{n \log n})$$$.
Because we add the same $$$x$$$ to all elements for a given range, the ordering in that range will not change. So, for each range, the question becomes finding $$$m \cdot a[l] + (m-1) \cdot a[l+1] + \ldots + 2 \cdot a[r-1] + 1 \cdot a[r]$$$ for the sorted $$$[l,r]$$$ range. Then we can just add $$$\frac{x \cdot m \cdot (m+1)}{2}$$$ to the result.
As yoshi_avx mentioned, the best solution is most probably Mo's and maybe a merge sort tree or segment tree solution, though I didn't find or write a solution yet.
It's also really easy to solve the problem in $$$O(nq \log n)$$$, for small $$$n$$$ and/or $$$q$$$.
The addition of x to the values from position l to r in the i-th query will apply to all queries from i + 1 onwards, it's not just applied locally in query i.IYou should modify the code to handle these cumulative effects. Besides the formula ((m — 1) * b[1] + (m — 1) * b[2] + .. + b[m]) % MOD, it is m — 1 at b[1].
Oh yeah true, I don't actually update the array's elements in the code. I wrote that in 5 mins lol let me update it so it's correct.
adding x on [l, r] doesn't change the ordering of [l, r] but might change the ordering of [l, r+1] (or any range containing elements both in and outside [l, r]).
e.g. [1, 2, 3, 4, 5] => [11, 12, 13, 14, 5]
True, I was only saying that as it might help with solving each individual query.
How do you calculate the contributions when the ranges partially intersects?
I have a $$$O(q \cdot n\sqrt{n} \cdot log(\sqrt{n}))$$$ idea which I think can be optimized
The answer to a query can be simplified into:
$$$\sum^{r}_{i=l} (a_i * (x + 1)) - min^{r}_{i=l} b_i$$$
where x is the number of indices $$$j$$$ such that $$$l \le j \le r, j \ne i, a_i \le a_j$$$
So we can do as follows
First we do sqrt decomposition on the array and sort every block
For every query, we go through every block:
If the block lies completely in the interval, add x to the lazy value corresponding to that block.
Else add x to every element in that block which has an index inside of the interval and sort the block
After updating, we can go through every element, perform binary search on every block to calculate the number of indices $$$j$$$. Finally, we subtract the minimim
It seems your formula for calculating the minimum sum of min(a[i], a[j]) doesn't yield the correct result for this problem. For example, with the input [3, 4, 5], you would return 3 + 3 + 4 = 2 * 3 + 4 instead of 2 * 3 + 2 * 4 + 5.Please double-check your logic.
oh mb, will fix it
Can you explain the idea more cleanly. Thanks
I doubt it's as efficient a solution as you want, but since no one has said it yet, it can be solved straightforwardly in O(n*log(n)+nq) by maintaining an indexed sorted list: after initial sort, for each query, split into two lists with indices inside range and outside range; add x to each array element in the inside range list and calculate the result directly. Then do O(n) sorted list merge to get our fully sorted list back.