Advertisement
bingxuan9112

小Y與小P

Jan 27th, 2020
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.01 KB | None | 0 0
  1. //   __________________
  2. //  | ________________ |
  3. //  ||          ____  ||
  4. //  ||   /\    |      ||
  5. //  ||  /__\   |      ||
  6. //  || /    \  |____  ||
  7. //  ||________________||
  8. //  |__________________|
  9. //  \###################\
  10. //   \###################\
  11. //    \        ____       \
  12. //     \_______\___\_______\
  13. // An AC a day keeps the doctor away.
  14.  
  15. #pragma g++ optimize("Ofast")
  16. #pragma loop_opt(on)
  17. #include <bits/extc++.h>
  18. #ifdef local
  19. #define debug(x) (cerr<<#x<<" = "<<(x)<<'\n')
  20. #else
  21. #include <bits/stdc++.h>
  22. #define debug(x) ((void)0)
  23. #endif // local
  24. #define all(v) begin(v),end(v)
  25. #define siz(v) (ll(v.size()))
  26. #define get_pos(v,x) (lower_bound(all(v),x)-begin(v))
  27. #define sort_uni(v) sort(begin(v),end(v)),v.erase(unique(begin(v),end(v)),end(v))
  28. #define pb emplace_back
  29. #define ff first
  30. #define ss second
  31. #define mem(v,x) memset(v,x,sizeof v)
  32.  
  33. using namespace std;
  34. using namespace __gnu_pbds;
  35. typedef int64_t ll;
  36. typedef long double ld;
  37. typedef pair<ll,ll> pll;
  38. typedef pair<ld,ld> pld;
  39. template <typename T> using max_heap = __gnu_pbds::priority_queue<T,less<T> >;
  40. template <typename T> using min_heap = __gnu_pbds::priority_queue<T,greater<T> >;
  41. template <typename T> using rbt = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
  42. constexpr ld PI = acos(-1), eps = 1e-5;
  43. constexpr ll N = 100025, INF = 1e18, MOD = 1000000007, inf = 1e9;
  44. constexpr inline ll cdiv(ll x, ll m) { return x/m + ((x<0 ^ m>0) && (x%m)); } // ceiling divide
  45. constexpr inline ll modpow(ll e,ll p,ll m=MOD) {ll r=1; for(e%=m;p;p>>=1,e=e*e%m) if(p&1) r=r*e%m; return r;}
  46.  
  47. struct DSU {
  48.     vector<pair<int,int> > ops;
  49.     int pa[N], sz[N], tr;
  50.     void init(int n){tr=0, iota(pa,pa+n+1,0), fill(sz,sz+n+1,1);}
  51.     int anc(int x){return x==pa[x] ? x : anc(pa[x]);}
  52.     void uni(int x, int y, int rec = false) {
  53.         if((x=anc(x)) == (y=anc(y))) return;
  54.         if(sz[x] < sz[y]) swap(x,y);
  55.         if(rec) ops.push_back({x,y});
  56.         ++tr, pa[y] = x, sz[x] += sz[y];
  57.     }
  58.     void undo(int t) {
  59.         while(ops.size() > t) {
  60.             int x = ops.back().first, y = ops.back().second;
  61.             ops.pop_back();
  62.             sz[x] -= sz[y], pa[y] = y;
  63.         }
  64.     }
  65. } dsu;
  66. vector<int> adj[N];
  67. vector<tuple<int,int,int> > Q[N]; // Q[block[l]] == {R,L,i};
  68. int ans[N],n,m,q;
  69. void add(int l, int r, int i, int rec = false) { // add i -> [l,r]
  70.     //for(int x: adj[i]) if(l <= x && x <= r) dsu.uni(i, x, rec);
  71.     int L = lower_bound(all(adj[i]), l) - adj[i].begin();
  72.     int R = upper_bound(all(adj[i]), r) - adj[i].begin();
  73.     for(int j = L; j < R; j++) dsu.uni(i,adj[i][j],rec);
  74. }
  75. int block[N], rb[N];
  76. signed main() {
  77.     //freopen("in.txt", "r", stdin);
  78.     //freopen("ou.txt", "w", stdout);
  79.     ios_base::sync_with_stdio(0), cin.tie(0);
  80.     cin >> n >> m >> q;
  81.     debug(n), debug(m), debug(q);
  82.     for(int i = 0; i < m; i++) {
  83.         int a, b;
  84.         cin >> a >> b;
  85.         adj[a].pb(b);
  86.         adj[b].pb(a);
  87.     }
  88.     for(int i = 1; i <= n; i++) sort(all(adj[i]));
  89.     // sigma deg == n+m*2
  90.     for(int i = 1, cnt = 512; i <= n; i++) {
  91.         if(cnt + adj[i].size() + 1 < 512) {
  92.             block[i] = block[i-1];
  93.         }else {
  94.             block[i] = block[i-1]+1;
  95.             cnt = 0;
  96.         }
  97.         cnt += adj[i].size() + 1;
  98.         rb[block[i]] = i;
  99.     }
  100.  
  101.     for(int i = 0; i < q; i++) {
  102.         int l, r;
  103.         cin >> l >> r;
  104.         Q[block[l]].push_back({r,l,i});
  105.     }
  106.  
  107.     for(int b = 0; b < N; b++) if(Q[b].size()) {
  108.         dsu.init(n);
  109.         sort(all(Q[b]));
  110.         int l, r = rb[b];
  111.         for(auto p: Q[b]) {
  112.             int i = get<2>(p);
  113.             int R = get<0>(p), L = get<1>(p);
  114.             l = min(R, rb[b]-1);
  115.             while(r <= R) add(l+1,r-1,r,0), r++;
  116.             int now = dsu.ops.size();
  117.             int tr = dsu.tr;
  118.             while(l >= L) add(l,R,l,1), l--;
  119.             ans[i] = R-L+1 - dsu.tr;
  120.             dsu.tr = tr;
  121.             dsu.undo(now);
  122.         }
  123.     }
  124.     for(int i = 0; i < q; i++) cout << ans[i] << '\n';
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement