Advertisement
welleyth

683. B (DSU RollBack)

May 26th, 2022 (edited)
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.04 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #include <ext/pb_ds/assoc_container.hpp>
  3. #include <ext/pb_ds/tree_policy.hpp>
  4. using namespace __gnu_pbds;
  5. using namespace std;
  6.  
  7. #define int long long
  8. #define mp make_pair
  9. #define pb push_back
  10.  
  11. #pragma GCC optimize("Ofast")
  12. #pragma GCC optimize("unroll-loops")
  13.  
  14. constexpr int INF = (int)1e18;
  15. constexpr int N = (int)5e5 + 111;
  16. constexpr int md = (int)1e9+7;
  17.  
  18. int parent[N];
  19. int sz[N];
  20. vector<pair<pair<int,int>,pair<int,int>>> history;
  21. int deep[N];
  22.  
  23. int get(int x){
  24.     if(parent[x] == x)
  25.         return x;
  26.     return get(parent[x]);
  27. }
  28.  
  29. void union_sets(int a,int b){
  30.     a = get(a), b = get(b);
  31.     if(a == b){
  32.         history.pb({{0,0},{0,0}});
  33.         return;
  34.     }
  35.     if(deep[a] > deep[b])
  36.         swap(a,b);
  37.     history.pb(mp(mp(a,parent[a]),mp(sz[b],deep[b])));
  38.     deep[b] = max(deep[b],deep[a]+1);
  39.     parent[a] = b;
  40.     sz[b] += sz[a];
  41.     return;
  42. }
  43.  
  44. bool connected(int a,int b){
  45.     return get(a) == get(b);
  46. }
  47.  
  48. void roll_back(){
  49.     assert(!history.empty());
  50.     int a = history.back().first.first, b = history.back().first.second, prevSZ = history.back().second.first;
  51.     int d = history.back().second.second;
  52.     history.pop_back();
  53.     sz[parent[a]] = prevSZ;
  54.     deep[parent[a]] = d;
  55.     parent[a] = b;
  56.     return;
  57. }
  58. vector<pair<int,int>> t[4*N];
  59. void upd(int v,int l,int r,int tl,int tr,pair<int,int>& x){
  60.     if(l > r || tl > tr)
  61.         return;
  62.     if(l == tl && r == tr){
  63.         t[v].pb(x);
  64.         return;
  65.     }
  66.     int m = (l+r)>>1;
  67.     upd(v<<1,l,m,tl,min(tr,m),x);
  68.     upd(v<<1|1,m+1,r,max(tl,m+1),tr,x);
  69.     return;
  70. }
  71.  
  72. vector<int> g[N];
  73. vector<pair<int,int>> edges;
  74. map<pair<int,int>,int> pr;
  75.  
  76. struct query{
  77.     int id,x,y;
  78.     int a = -1, b = -1;
  79.     query(){}
  80.     query(int x,int y,int id):x(x),y(y),id(id){}
  81.     query(int x,int y,int a,int b,int id):x(x),y(y),a(a),b(b),id(id){}
  82. };
  83.  
  84. vector<query> QueriesSec[N];
  85. vector<query> QueryEdge;
  86.  
  87. bool ans[N];
  88. vector<pair<int,int>> current;
  89.  
  90. void go(int v,int l,int r){
  91.     for(auto&[x,y] : t[v]){
  92. //        cerr << "adding " << x << " " << y << "\n";
  93.         union_sets(x,y);
  94. //        current.pb(mp(x,y));
  95.     }
  96.     if(l == r){
  97. //        cerr << "l,r = " << l << " " << r << "\n";
  98. //        for(auto&[x,y] : current){
  99. //            cerr << x << " " << y << "\n";
  100. //        }
  101. //        cerr << "\n";
  102.         for(auto& q : QueriesSec[l]){
  103.             int& id = q.id, x = q.x, y = q.y;
  104.             ans[id] = connected(x,y);
  105. //            cerr << "x,y = " << x << " " << y << "\n";
  106.         }
  107.     } else {
  108.         int m = (l+r)>>1;
  109.         go(v<<1,l,m);
  110.         go(v<<1|1,m+1,r);
  111.     }
  112.     for(auto&[x,y] : t[v]){
  113. //        cerr << "removing " << x << " " << y << "\n";
  114.         roll_back();
  115. //        current.pop_back();
  116.     }
  117.     return;
  118. }
  119.  
  120. void solve(){
  121.     int n,m;
  122.     cin >> n >> m;
  123.  
  124.     for(int i = 0; i < m; i++){
  125.         int a,b;
  126.         cin >> a >> b;
  127.         if(a > b)
  128.             swap(a,b);
  129.         edges.pb(mp(a,b));
  130.         g[a].pb(b);
  131.         g[b].pb(a);
  132.     }
  133.  
  134.     for(int i = 1; i <= n; i++){
  135.         for(auto& to : g[i]){
  136.             int a = i, b = to;
  137.             if(a > b)
  138.                 swap(a,b);
  139.             pair<int,int> e = mp(a,b);
  140.             upd(1,1,n,pr[mp(a,b)]+1,i-1,e);
  141.             pr[mp(a,b)] = i;
  142.         }
  143.     }
  144.  
  145.     for(int i = 0; i < N; i++){
  146.         parent[i] = i;
  147.         deep[i] = 1;
  148.     }
  149.  
  150.     for(auto& x : edges){
  151.         upd(1,1,n,pr[x]+1,n,x);
  152.     }
  153.     int q;
  154.     cin >> q;
  155.  
  156.     for(int i = 1; i <= q; i++){
  157.         int tp;
  158.         cin >> tp;
  159.         int x,y;
  160.         cin >> x >> y;
  161.         if(tp == 1){
  162.             int a,b;
  163.             cin >> a >> b;
  164.             QueryEdge.pb(query(x,y,a,b,i));
  165.         } else {
  166.             int a;
  167.             cin >> a;
  168.             QueriesSec[a].pb(query(x,y,i));
  169.         }
  170.     }
  171.  
  172.     go(1,1,n);
  173. //    for(int i = 1; i <= q; i++)
  174. //        cerr << (ans[i] ? "Yes" : "No") << "\n";
  175. //    cerr << "\n";
  176. //    return;
  177.  
  178.     pr.clear();
  179.  
  180.     for(int i = 0; i < 4*N; i++){
  181.         t[i].clear();
  182.     }
  183.     for(int i = 0; i < N; i++){
  184.         QueriesSec[i].clear();
  185.     }
  186.  
  187.     int i = 1;
  188.     int sz = QueryEdge.size()+1;
  189.     for(int i = 0; i < N; i++){
  190.         parent[i] = i;
  191.         deep[i] = 1;
  192.     }
  193.     assert(history.empty());
  194.     history.clear();
  195.  
  196.     for(auto& q : QueryEdge){
  197.         QueriesSec[i].pb(q);
  198.         int& a = q.a, b = q.b;
  199.         if(a > b)
  200.             swap(a,b);
  201.         pair<int,int> e = mp(a,b);
  202.         upd(1,1,sz,pr[e]+1,i-1,e);
  203.         pr[e] = i++;
  204.     }
  205.  
  206.     for(auto& x : edges){
  207.         upd(1,1,sz,pr[x]+1,sz,x);
  208.     }
  209.  
  210.     go(1,1,sz);
  211.  
  212.     for(int i = 1; i <= q; i++){
  213.         cout << (ans[i] ? "yes" : "no") << "\n";
  214.     }
  215.  
  216.     return;
  217. }
  218.  
  219. signed main(){
  220.     ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
  221.     int tests = 1;
  222. //    cin >> tests;
  223.     for(int test = 1; test <= tests; test++){
  224.         solve();
  225.     }
  226.     return 0;
  227. }
  228. /**
  229. no
  230. yes
  231. yes
  232. no
  233. yes
  234. yes
  235. yes
  236. yes
  237. yes
  238. yes
  239. yes
  240. no
  241. yes
  242. yes
  243. yes
  244. no
  245. yes
  246. yes
  247.  
  248. **/
  249.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement