Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- void dbg_out() { cerr << endl; }
- template<typename Head, typename... Tail>
- void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }
- #define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
- #define rng_init mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
- #define rng_seed(x) mt19937 rng(x)
- #define all(x) (x).begin(), (x).end()
- #define sz(x) (int) (x).size()
- // #define int long long
- struct UFDS {
- int n, components;
- vector<int> info;
- UFDS(int _n = 0) { init(_n); }
- void init(int _n) {
- n = _n;
- components = n;
- info.assign(n, -1);
- }
- int find(int x) { return info[x] < 0 ? x : info[x] = find(info[x]); }
- bool unite(int u, int v) {
- u = find(u), v = find(v);
- if (u == v) return false;
- if (info[u] > info[v]) swap(u, v);
- info[u] += info[v];
- info[v] = u;
- components--;
- return true;
- }
- bool connected(int u, int v) { return find(u) == find(v); }
- int component_count() { return components; }
- };
- const int MXN = 1e5 + 5, INF = 1e9 + 5;
- void solve() {
- int N, M, Q;
- cin >> N >> M >> Q;
- vector<pair<int, int>> edges(M);
- for (int i = 0; i < M; i++) {
- cin >> edges[i].first >> edges[i].second;
- edges[i].first--, edges[i].second--;
- }
- vector<int> block(M);
- int block_size = sqrt(M);
- for (int i = 0; i < M; i++)
- block[i] = i / block_size;
- vector<pair<int, int>> queries[M];
- for (int i = 0; i < Q; i++) {
- int l, r;
- cin >> l >> r;
- l--, r--;
- queries[r].emplace_back(l, i);
- }
- vector<int> ans(Q);
- vector<UFDS> ufds(block_size + 5, UFDS(N));
- UFDS temp(N);
- vector<int> last(N, -1), last_rem;
- for (int i = 0; i < M; i++) {
- for (int cur_block = block[i]; cur_block >= 0; cur_block--)
- ufds[cur_block].unite(edges[i].first, edges[i].second);
- for (int q = 0; q < sz(queries[i]); q++) {
- int l = queries[i][q].first, idx = queries[i][q].second;
- if (block[l] == block[i]) {
- for (int j = l; j <= i; j++)
- temp.unite(edges[j].first, edges[j].second);
- ans[idx] = temp.component_count();
- for (int j = l; j <= i; j++) {
- temp.info[edges[j].first] = -1;
- temp.info[edges[j].second] = -1;
- }
- temp.components = N;
- continue;
- }
- ans[idx] = ufds[block[l] + 1].component_count();
- for (int j = l; block[l] == block[j] && j <= i; j++) {
- int u = edges[j].first, v = edges[j].second;
- int p1 = ufds[block[l] + 1].find(u), p2 = ufds[block[l] + 1].find(v);
- if (last[p1] > -1) temp.unite(u, last[p1]);
- if (last[p2] > -1) temp.unite(v, last[p2]);
- last[p1] = u;
- last[p2] = v;
- last_rem.push_back(p1);
- last_rem.push_back(p2);
- }
- for (int j = l; block[l] == block[j] && j <= i; j++) {
- int u = edges[j].first, v = edges[j].second;
- ans[idx] -= temp.unite(u, v) && !ufds[block[l] + 1].connected(u, v);
- }
- for (int j = l; block[l] == block[j] && j <= i; j++)
- temp.info[edges[j].first] = temp.info[edges[j].second] = -1;
- for (const auto &x : last_rem)
- last[x] = -1;
- last_rem.clear();
- temp.components = N;
- }
- }
- for (const auto &x : ans)
- cout << x << "\n";
- }
- signed main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- int TC = 1;
- cin >> TC;
- while (TC--) solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement