ABC219 G - Propagation(圖分塊)
阿新 • • 發佈:2021-10-28
目錄
Description
有一個圖有 \(n\) 個節點,\(m\) 條邊,每個點由它對應的編號和權值,初始時權值為編號,有 \(Q\) 次操作,可以將與 \(x\) 節點相連的所有節點的權值變為 \(x\) 節點的權值,求最後所有節點的權值
State
\(1<=n<=2*10^5\)
\(0<=m<=min(2*10^5,\frac{n(n-1)}{2})\)
\(1<=Q<=2*10^5\)
\(1<=u_i<=v_i<=n\)
\(1<=x_i<=n\)
Input
5 6 3
4 2
4 3
1 2
2 3
4 5
1 5
1 3 4
Output
1 3 3 3 3
Solution
如果每一次更新去暴力求解,時間複雜度為 \(O(Q*m)\)
很容易看出時間複雜度與每個節點的度有關,這時就需要利用圖分塊將度比較大的節點延遲處理
根據套路,如果節點 \(u\) 連線的一個節點 \(v\) 的度過大,那麼將這個節點 \(v\) 作為與 \(u\) 相連線的節點
對於每次操作 \(x\), 如果 \(x\)
否則將其所連線的節點暴力修改即可。
當前 \(x\) 節點的答案為其所連重點的 \(lazy\) 之一(可以不包含當前 \(x\) 節點的 \(lazy\))
Code
const int N = 2e5 + 5; int n, m, k, _; vector<int> G[N], G2[N]; int block; pii ans[N], lag[N]; signed main() { // IOS; int Q; while(~ sddd(n, m, Q)){ int x, y; rep(i, 1, m){ sdd(x, y); G[x].pb(y); G[y].pb(x); } block = sqrt(m); for(int i = 1; i <= n; i ++){ for(int j = 0; j < G[i].size(); j ++){ x = G[i][j]; if(G[x].size() > block) G2[i].pb(x); } } for(int i = 1; i <= n;i ++) ans[i] = lag[i] = {i, 0}; for(int k = 1; k <= Q; k ++){ sd(x); for(auto it : G2[x]){ if(lag[it].se > ans[x].se){ ans[x] = lag[it]; } } if(G[x].size() <= block){ for(auto it : G[x]){ ans[it] = {ans[x].fi, k}; } } else{ // lag[x] = {ans[x].fi, k}; 同樣 AC ans[x] = lag[x] = {ans[x].fi, k}; } } for(int i = 1; i <= n; i ++){ for(auto it : G2[i]){ if(lag[it].se > ans[i].se){ ans[i] = lag[it]; } } printf("%d ", ans[i].fi); } puts(""); } // PAUSE; return 0; }