Explanation
The problem asks us to find the number of pairs of nodes that are reachable from each other, so it suffices to keep track of the size of each connected component. If there are connected components and the th component has size , then the number of reachable pairs is
since two nodes are reachable if and only if they belong to the same connected component. To maintain the values of , we can use a Disjoint Set Union (DSU).
At each timestamp , if , then all edges incident to node are removed, which splits the node 's component into multiple components. If , then node is removed from its component, but edges are added between all pairs of node 's neighbors, preventing the component from splitting. Instead of adding all of these extra edges, we can just "deactivate" node , reducing its component's size by , while keeping edges adjacent to it. This works because any two of node 's neighbors can only become disconnected when one of them is removed.
Since removing edges is not possible on a DSU, we instead simulate the process in reverse, starting with the final graph's DSU and adding edges and nodes as we go backwards. To create this final graph, we set the sizes of the components of nodes where to (all other components should start with size ). Then, connect all edges between nodes and where . Now, we process each in reverse. If , then increase the size of node 's component by . Otherwise, if , add all edges incident to node to our DSU.
To compute the answer, we can store a variable (initially equal to ). Whenever two components of size and are linked, add to (since each pair of nodes with one node from each of the two components is now reachable). Whenever the size of a component is changed from to , add to (since the added node creates reachable pairs, one with each other node in its component).
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>using namespace std;using ll = long long;struct DSU {// s is size of component, p is parentvector<int> p, s;DSU(int n) : p(n, -1), s(n, 1) {}int parent(int x) {if (p[x] == -1) return x;
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!