Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
offline_dynamic_connectivity.hpp
[詳解]
1#include"../../kyopro_library/template.hpp"
2#include"../../kyopro_library/graph/dsu_rollback.hpp"
3
4/// @brief オフラインのDinamic Connectiviy
6 /// @brief コンストラクタ
7 /// @param v 頂点数
8 /// @param q クエリ数
9 DynamicConnectivity(int v, int q) {
10 n=q;
11 edges=vector<vector<P>>(2*n);
12 dsu=DsuRollback(v);
13 }
14
15 /// @brief 時間 time に頂点 u, v を連結する
16 void unite(int time, int u, int v) {
17 P e=minmax(u,v);
18 if(count[e]++==0) appear[e]=time;
19 }
20
21 /// @brief 時間 time に頂点 u, v を切断する
22 void cut(int time, int u, int v) {
23 P e=minmax(u,v);
24 if(--count[e]==0) period.push_back({{appear[e],time},e});
25 }
26
27 /// @brief クエリ処理の前計算を行う
28 void build() {
29 for(auto [e,val]: count) if(val>0) period.push_back({{appear[e],n},e});
30 for(auto [range,e]: period) {
31 auto [l,r]=range;
32 l+=n,r+=n;
33 while(l<r) {
34 if(l&1) edges[l++].push_back(e);
35 if(r&1) edges[--r].push_back(e);
36 l>>=1,r>>=1;
37 }
38 }
39 }
40
41 /// @brief クエリ関数 f を処理する
42 void execute(auto& f, int k=1) {
43 if(k>=2*n) return;
44 for(auto [u,v]: edges[k]) dsu.merge(u,v);
45 if(k<n) {
46 execute(f,k<<1);
47 execute(f,k<<1|1);
48 } else if(0<=k-n && k-n<n) {
49 int query_idx=k-n;
50 f(query_idx);
51 }
52 for(auto [u,v]: edges[k]) dsu.undo();
53 }
54
55private:
56 using P=pair<int,int>;
57 DsuRollback dsu;
58 int n;
59 vector<vector<P>> edges;
60 vector<pair<P,P>> period;
61 map<P,int> count,appear;
62};
ロールバック可能DSU
オフラインのDinamic Connectiviy
void execute(auto &f, int k=1)
クエリ関数 f を処理する
void unite(int time, int u, int v)
時間 time に頂点 u, v を連結する
DynamicConnectivity(int v, int q)
コンストラクタ
void cut(int time, int u, int v)
時間 time に頂点 u, v を切断する
void build()
クエリ処理の前計算を行う