Table of Contents

ExplanationImplementation

Official Analysis (C++)

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 kk connected components and the iith component has size aia_i, then the number of reachable pairs is

i=1k(ai2)\sum_{i=1}^{k}{\binom{a_i}{2}}

since two nodes are reachable if and only if they belong to the same connected component. To maintain the values of aia_i, we can use a Disjoint Set Union (DSU).

At each timestamp ii, if si=0s_i = 0, then all edges incident to node ii are removed, which splits the node ii's component into multiple components. If si=1s_i = 1, then node ii is removed from its component, but edges are added between all pairs of node ii's neighbors, preventing the component from splitting. Instead of adding all of these extra edges, we can just "deactivate" node ii, reducing its component's size by 11, while keeping edges adjacent to it. This works because any two of node ii'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 si=1s_i = 1 to 00 (all other components should start with size 11). Then, connect all edges between nodes ii and jj where si=sj=1s_i = s_j = 1. Now, we process each sis_i in reverse. If si=1s_i = 1, then increase the size of node ii's component by 11. Otherwise, if si=0s_i = 0, add all edges incident to node ii to our DSU.

To compute the answer, we can store a variable ansans (initially equal to 00). Whenever two components of size xx and yy are linked, add xyxy to ansans (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 xx to x+1x+1, add xx to ansans (since the added node creates xx reachable pairs, one with each other node in its component).

Implementation

Time Complexity: O((N+M)α(n))\mathcal{O}((N + M) \cdot \alpha(n))

C++

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct DSU {
// s is size of component, p is parent
vector<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!