題意見洛谷。(以下認為所有\(\log\)同階,用\(\log n\)表示)
首先在我認知範圍內似乎稍微複雜一點的圖上詢問題都沒有polylog做法。先來考慮暴力。
先上乙個sb都會的暴力:修改就直接改,查詢就把所有符合條件的邊連起來建出一張圖跑dfs。\(\mathrm o(qm)\)。
再考慮乙個稍微經過大腦的想法。假如問題是靜態的話,我們可以將所有邊和所有詢問排個序,使得在之前有的邊之後一定有,這樣就可以two-pointers地遞推建圖了,並查集維護連通性即可。但是有修改怎麼辦呢?依然排序,只將永遠不會被修改的邊排序按上述方法加,有修改的邊的話就把修改它的操作有序地存下來,每次查詢就二分查詢出每條有修改的邊最後一次修改並符合條件就加入並查集,得出答案後撤銷。時間複雜度\(\mathrm o\!\left(m\log n+q^2\log n\right)\)。
事實上這兩種暴力並不能視作並列。不難發現,暴力一單次操作複雜度僅與\(m\)相關,暴力二單次操作複雜度僅與\(q\)相關,但是暴力二還有乙個單獨的\(m\),而且這個\(m\)和暴力一里的\(m\)是做的同樣的工作:往圖裡加邊。如果把暴力一的dfs也看成並查集的話,完全可以這樣理解:暴力二是一些連續的操作離線下來排序,可以將所有操作分成若干段抱團取暖,暴力二本質上是\(1\)段,而暴力一是\(q\)段。
顯然這兩種分段方式都太極端了。不妨強行令每段大小相等,這樣就有了分塊的想法:每段\(sz1\)個操作,共\(\mathrm o\!\left(\dfrac q\right)\)段。這樣總時間複雜度顯然是\(\mathrm o\!\left(\dfrac q(m\log n+sz1^2\log n)\right)=\mathrm o\!\left(\dfrac+q\cdot sz1\log n\right)\)。根據均值不等式,\(sz1=\sqrt m\)時時間複雜度為最優為\(\mathrm o(q\sqrt m\log n)\),如果你常數跟我一樣大就別想了老老實實優化吧,如果你常數跟fz一樣小可以考慮卡過去。
考慮優化。接下來分析複雜度的時候不考慮線性和線性乘以\(\log\)的操作,因為它們對複雜度的影響實在是微乎其微。把剩下來的操作都拎出來整理一遍。
將沒有修改的邊排序:每塊都要排一遍,\(\mathrm o\!\left(\dfrac\right)\);
將沒有修改的邊加入可撤銷並查集:每塊都要加一遍,\(\mathrm o\!\left(\dfrac\right)\);
將有修改的邊加入可撤銷並查集:\(\mathrm o\!\left(q\cdot sz1\log n\right)\)。
考慮操作\(1\)。注意到這一塊和上一塊都沒有修改的邊一定是排好序的了,我們只需要將上一塊有修改這一塊沒有修改的邊拎出來排序然後和之前那個歸併一下即可。而第二類那種邊單塊只能有\(\mathrm o(sz1)\)條,總共就是\(\mathrm o(q)\)條。於是操作\(1\)的\(\log\)沒了。然鵝複雜度沒有變,因為下面有個複雜度一樣的操作(悲)
考慮操作\(2\)。顯然這一部分是永遠不會被撤銷的,於是這一部分改到普通並查集模式,路徑壓縮+啟發式合併可以變\(\log\)為\(\alpha\)。至此總複雜度降到了\(\mathrm o\!\left(q\sqrt\right)\)。(還是很大)
考慮操作\(3\)。可以並查集縮點,然後暴力連邊跑dfs。這樣複雜度顯然是少了乙個\(\log\)了的。至此,令\(sz1=\sqrt\)即可擁有\(\mathrm o\!\left(q\sqrt\right)\)的總複雜度。
(所以這個時間軸分塊到底是啥套路,不太摸得清)
下面貼**:
#includeusing namespace std;
#define mp make_pair
#define x first
#define y second
#define pb push_back
const int n=50000,m=100000,qu=100000;
int n,m,qu;
int a[m+1],b[m+1],w[m+1];
struct queryqry[qu+1];
int ans[qu+1];
vectorchged,unchged;
int las_unchged[m+1];
vectorchgid[m+1];
vectorask;
bool cmp(int x,int y)
bool cmp0(int x,int y)
struct ufset
int root(int x)
void mrg(int x,int y)
int _sz(int x)
}ufs;
struct addedge
void ae(int x,int y)
}nei;
vectorcc;
bool vis[n+1];
int dfs(int x)
return res;
}int main()
sort(v.begin(),v.end(),cmp0);
for(int j=0;jw0)continue;
int ar=ufs.root(a[chged[k]]),br=ufs.root(b[chged[k]]);
nei.ae(ar,br),nei.ae(br,ar);
}ans[ask[j]]=dfs(ufs.root(qry[ask[j]].x));
for(int k=0;kfor(int k=0;kcc.clear();
} for(int j=i;j<=ie;j++)if(qry[j].tp==1)w[qry[j].x]=qry[j].y;
} for(int i=1;i<=qu;i++)if(qry[i].tp==2)printf("%d\n",ans[i]);
return 0;
}
洛谷P5443 APIO2019 橋梁
apio場外選手沒事休閒做題。看了yyb的題解才把這題做出來 對操作進行分塊,把每 text 個操作分成1組,裡面大概有2類 沒被修改過的和被修改過的。接著對塊內詢問進行離線。對於沒有修改過的 我們可以直接排序然後把他們加入並查集。對於修改過的,我們看他的時間是否大於當前操作的時間,如果大於則加入原...
洛谷P5049 洛谷P5022 題解 旅行
原題 資料加強版 加強版 參考你谷題解 終於調過了 又是一如既往的申必錯誤 noi plus石錘了 原題的資料允許我們 o n 2 暴力斷邊,但是加強版的資料達到了 n log n 級別,我們必須在斷邊這一環節尋求更好的解法。考慮我們進入環後在何處回溯 根據繼續走環走到的點分類 設當前已經從 b 走...
洛谷練習P2279 P1346
2020年,人類在火星上建立了乙個龐大的基地群,總共有n個基地。起初為了節約材料,人類只修建了n 1條道路來連線這些基地,並且每兩個基地都能夠通過道路到達,所以所有的基地形成了乙個巨大的樹狀結構。如果基地a到基地b至少要經過d條道路的話,我們稱基地a到基地b的距離為d。由於火星上非常乾燥,經常引發火...