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