Of course, offline, both tasks can be solved using Mo algorithm and 3DMo (there are many ways like scanline, etc.), but there are some problems where we need to answer queries online. The solution with a persistent segment tree, i heard from Andrew-13, is good, but it does not support update queries. So, let's get started and learn how to solve both problems.
Problem 1: $$$O(log(n)^2)$$$ on query using 2D Implicit Segment Tree
What is a "unique" element in a subarray? — an element in a subarray $$$a[ l, r ]$$$ is considered unique if it appears exactly once in that range => it's previous occurrence (if any) is before $$$l$$$ and it's next occurrence (if any) is after $$$r$$$.
Let's introduce the definition: link of $$$a_i$$$ is a reference that points to an equal element that is located closer to the left/right than others. If there are no such links, the left link leads to $$$-1$$$, and the right link leads to $$$n$$$.
Now we need to find the number of elements on $$$[ l, r ]$$$ such that their left links point to elements at positions < $$$l$$$, and the right links to elements at positions > $$$r$$$. So, let's build $$$future$$$ and $$$last$$$ — arrays containing links to the closest equal elements:
- $$$future_i$$$ contains the index of the closest element equal to $$$a_i$$$ on the right (or $$$n$$$ if there are no such elements).
- $$$last_i$$$ contains the index of the closest element equal to $$$a_i$$$ on the left (or $$$-1$$$ if there are no such elements).
We will consider current query: $$$[ l, r ]$$$. Let's just count elements with $$$future_i$$$ > $$$r$$$ and $$$last_i$$$ < $$$l$$$ => — $$$last_i$$$ > — $$$l$$$ => $$$1000000$$$ — $$$last_i$$$ > $$$1000000$$$ — $$$l$$$. Now all coordinates are positive, because $$$l$$$, $$$last_i$$$ < $$$n$$$ < $$$10^5$$$.
So, we need to count the number of points ($$$x_i$$$, $$$y_i$$$) = ($$$1000000$$$ — $$$last_i$$$, $$$future_i$$$) which lie in the upper right part of plane relative to ($$$minX$$$, $$$minY$$$) = ($$$1000000$$$ — $$$l$$$, $$$r$$$). 2D Implicit Segment Tree can easily solve this problem in $$$O(log(n)^2)$$$.
This would be a solution if there were no points:
- lies before the left border and the right link crosses the right border.
- lies after the right border and the left link crosses the left border.
So, we get the number of unnecessary points and subtract it from the total answer. This can be realized with simple Segment Tree with Treaps in nodes, because we actually need to be able to answer to 2 queries:
- count the number of elements on [ $$$0$$$, $$$l$$$ — $$$1$$$ ] that have right links > $$$r$$$.
- count the number of elements on [ $$$r$$$ + $$$1$$$, $$$n$$$ — $$$1$$$ ] that have left links < $$$l$$$.
Finally: Precalc ~ $$$O(n * log(n)^2)$$$; Answer to query ~ $$$O(log(n)^2)$$$.
Problem 2: $$$O(log(n)^2)$$$ on query using 2D Implicit Segment Tree
What about update queries? Note that we can also easily answer them in $$$O(log(n)^2)$$$. Let's call $$$L$$$ — the maximum position in $$$a$$$ that < $$$i$$$ and $$$a_L$$$ = $$$X$$$; $$$F$$$ — the minimum position in $$$a$$$ that > $$$i$$$ and $$$a_F$$$ = $$$X$$$, where $$$X$$$ is the element in the update query. If there are no such elements, just put: $$$L$$$ = $$$-1$$$; $$$F$$$ = $$$n$$$.
When updating an element $$$a_i$$$, the links only change:
- $$$a[i]$$$ links.
- $$$a[last_i]$$$ links.
- $$$a[future_i]$$$ links.
- $$$a[L]$$$ links.
- $$$a[F]$$$ links.
It remains to remember to update Segment Tree of Treaps and the points on the 2D Segment Tree plane.
Finally: Precalc ~ $$$O(n * log(n)^2)$$$; Answer to query ~ $$$O(log(n)^2)$$$.
You can find my solution here.



