You are given an array which have at most 200000 elements. After that there are q queries. q<=200000. Each query contains three numbers s,e,k. How to for each query answer how many numbers in range [s,e] appear exactly k times? Is there any possibility to solve this without Mo's algorithm?
how do you solve it with mo's?
Let's define $$$f(x)$$$ as the frequency of $$$x$$$ in $$$[l, r]$$$, and $$$g(x)$$$ as the number of times frequency $$$x$$$ appeared in $$$[l, r]$$$. Mo's works by "moving" the range for a total of at most $$$\sqrt{n}$$$ times, and each move only takes $$$\mathcal{O}(1)$$$, so we can do this in a total of $$$\mathcal{O}(n\sqrt{n})$$$
Merge sort tree in
O((N + Q) log^2(N))
? Store a map for each range in the segment tree.Constant factor might be too slow for AC though, especially since
N,Q <= 200000
. Mo's is probably best.Let's define
nums
of typemap<int, vector<int>>
, so thatnums[k]
returns the list of numbers that appear exactly k times.Then sort the initial array.
During each query find the
it1 = lower_bound(a.begin(), a.end(), s)
andit2 = upper_bound(a.begin(), a.end(), e) - 1
, which return the leftmost item, not less than s and the rightmost number, not greater than e respectively. Then letit3 = nums.lower_bound(*it1)
and chech whether*it3 <= *it2
. If condition is satisfied, answer is yes, otherwise it's no.The total time complexity is
O(n log(n))
Upd: oops, didn't see that $$$k$$$ changes on each query. Anyways, here is a solution if $$$k$$$ is fixed throughout.
There is an offline segment tree solution. We will scan the array from left to right and maintain a segment tree. When we are standing at position $$$R$$$, we want the segment tree to store the following data:
For all $$$L$$$ from $$$1$$$ to $$$R$$$: $$$tree[L] =$$$ how many numbers in range $$$[L, R]$$$ appear exactly $$$k$$$ times. Notice that every number $$$X$$$ increments only a particular range of $$$tree$$$: the range between the $$$k$$$-th and $$$(k+1)$$$-th occurence of $$$X$$$ from the back collected so far (up to $$$R$$$).
When we step from $$$R$$$ to $$$R+1$$$, the segment tree does not change too much: the only contribution that changes is the one of $$$A[R+1]$$$. We just need to decrement the previous range, and increment the new range.
Answering a query $$$[s,e]$$$ is simple: when $$$R=e$$$, we extract $$$tree[s]$$$.
So, for this problem you just need a segment tree which allows segment increment + extract single element. You can do it with lazy prop, but actually just a Fenwick tree is enough. TC: $$$O(n \log n)$$$.