Problem
In python, we can use len(start(a[L:R])) to calculate the number of distinct values of elements a[L], a[L+1], …, a[R-1].
Here are some interactive examples that may help you understand how it is done. Remember that the indices of python lists start from 0.
|
|
Your task is to simulate this process.
Input
There will be only one test case. The first line contains two integers n and m (1 ≤ n,m ≤ 50,000). The next line contains the original list.
All the integers are between 1 and 1,000,000 (inclusive). The next m lines contain the statements that you need to execute.
A line formatted as “M x y” (1 ≤ y ≤ 1,000,000) means “a[x] = y”, and a line formatted as “Q x y” means “print len(set(a[x:y]))”.
It is guaranteed that the statements will not cause “index out of range” error.
Output
Print the simulated result, one line for each query.
Sample Input
|
|
Output for Sample Input
|
|
Solution
題目描述:
- 支持查找區間內有多少不同數字。
- 支持單點值修改
題目解法:
維護每一個數字的前面相同數字的位置,如果前面沒有一樣的就是 -1
|
|
對於詢問 [l, r],返回 P[l, r] 內小於 l 的個數。
這裡使用塊狀表維護資訊,也可以使用 線段樹 + 平衡樹。
塊狀表 作法
- 對於詢問
對於完整的塊進行二分搜尋。如果所在是不完整的塊,則窮舉搜尋。 對於修改
- 向後搜索舊值
將指向自己的修改成原本指向的。 - 向前搜索新值
將指向連到前方的相同數字。 - 向後搜索新值
將後面最靠近的相同數字連向自己。
- 向後搜索舊值
維護資訊
- 堆的 prev 排序後的資訊
用在詢問 query 區間內小於 l 的二分搜 - 堆的 value 排序後的資訊
維護 prev 時,查找前一個和後一個的時候使用。
- 堆的 prev 排序後的資訊
- 堆更新時,最簡單是直接排序,複雜度
O(sqrt(n) * log(sqrt(n)))
看起來是不會很多,如果不使用這種方式,則必須對 prev 和 value 數組增加映射來找到相對應的原位置,然後用插入排序的方式,達到O(sqrt(n))
。但是在 UVa 運行前者在 1.200 s 左右,基本上可以不用再優化,紀錄的資訊增加一倍 又或者 代碼要長一點。
- 對於詢問
每一個操作約在 O(sqrt(n))
時間內完整,塊狀表不用做合併操作。
|
|