競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 238E

ABC238E

累積和をを求めるのと同値.
\(s_{i} := \sum_{j \in i} a_{i}\)とする. 与えられる情報は,\(s_{r} - s_{l}\) となる. ここで \(s_{l}, s_{r}\) の内,一方が分かればもう一方が分かることになる. また,最初に分かっていることは,\(s_{0} = 0\) ということだけである.

これらを整理すると,グラフで考えることができる. 頂点は \(0, 1, \cdots N+1\) とする.つまり,累積和 \(s\) の index. 与えられた情報を \(s_{r} - s_{l}\) とする. このとき,頂点\(r,l\)を辺で結ぶ.
この様にして得られたグラフの中で, ある頂点 \(i \in N+1\) について \(s_{i}\) が分かったとすると, \(i\) と同じ connected component に属する任意の\(j \in N+1\) に対しても \(s_{j}\ が分かる.
つまり,初期状態で分かっている点達と同じ connected component に属する点 \(i \in N+1\) に対して \(s_{i}\) が特定できる. 逆に,それ以外の点は特定できない.
初期で分かっているのは \(s_{0}\) のみだったので, 判定は \(0, N+1\) が同じ connected component に属するかで良い.

使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"

int main() {
  ll n, q ;
  cin >> n >> q;
  UnionFind<ll> uf(n+1);
  rep(qi,q){
    ll l,r; cin >> l >> r;
    --l,--r;
    r++;
   
    uf.merge(l,r);
  }

  yesno(uf.same(0,n));
 

  return 0;
}