題目大意:給出一個 n 個點和 m 條邊的無向圖,每個點都有一個權值,現在需要執行?q 次操作,每次操作分為兩種類型:
1 pos val :將第 pos 個點的權值修改為 val
2 pos :詢問第 pos 個點相鄰的所有點的權值組成的集合的 mex
題目分析:只能說數據水了,如果數據拉滿 std 的復雜度應該是會 TLE 的
很顯然的幾個結論是:
設點 u 的度數為 du[ u ] ,則 mex( u ) 的答案一定小于等于 du[ u ]
度數大于等于 sqrt( n?) 的點的個數一定小于等于 sqrt( n ) 個
這樣一來考慮 sqrt 分塊,對于每個度數大于 sqrt( n ) 的結點維護一個樹狀數組,樹狀數組記錄一下相鄰的結點的權值都出現了哪些,這樣就可以二分去統計出 mex 了
綜上所述,對于操作 1 ,只需要更新?pos 結點周圍所有度數大于 sqrt( n ) 的結點的樹狀數組就好了,因為最多只有 sqrt( n ) 個結點,最壞情況就是這個 pos 結點連接了 sqrt( n ) 個結點,對于每個節點的更新,只需要對樹狀數組進行單點更新,所以最壞的時間復雜度為 sqrt( n ) * log n
對于操作 2 ,如果 pos 節點的度數小于 sqrt( n ) 的話,直接暴力查詢就好了,時間復雜度為 sqrt( n ) ,如果度數大于等于 sqrt( n ) 的話,就以 logn * logn 的時間復雜度在樹狀數組上二分就可以查詢答案了
總的時間復雜度為 T * n * sqrt( n ) * logn
注意,因為對于這個思路來說,只需要對于度數大于等于 sqrt( n ) 建立一個更新 + 查詢都是 log 級別的數據結構即可,也不難想到用 set 維護 0 ~ du[ i ] 內沒有出現的數字,亦或者直接在線段樹上二分,不過前者好像是常數太大,無論如何優化仍然 TLE,后者是因為區間大小問題不方便操作(或許可以用線段樹AC,不過個人感覺樹狀數組來寫這個題目更為簡單)