競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 302E

ABC302E

同じ頂点同士を結んだ辺であっても, 追加される度に別の辺として考える.
各辺に対して, 高々1回ずつしか追加と削除が行われない. 言い換えると,追加の回数が合計\(x\)回なら, 削除の回数は合計\(y \leq x\)回しか行われない.
一方,\(x \leq Q\)であるから, 合計で\(x + y \leq 2Q\)回しか行われない.

実装: 問題文通りに実装する. ただし,\(i \in N\) に対して to[i]から元を削除することになるので, to[i] を set で持っておく. 辺を追加または削除したとき,辺に使われている頂点だけが, 孤立点になるか否か変化する可能性がある.
計算量: \(O(Q log N)\)

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

int main() {
  ll n, q ;
  cin >> n >> q;

  vector<set<ll>> to(n);
  ll x = n;
 
  rep(qi,q){
    ll ty, a, b; cin >> ty;
    if(ty == 1){
      cin >> a >> b;
      --a, --b;

      if(to[a].size() == 0) x--;
      if(to[b].size() == 0) x--;

      to[a].insert(b);
      to[b].insert(a);
     
    }else{
      cin >> a;
      --a;

      if(to[a].size()){
        x++;
        for(auto i: to[a]){
          to[i].erase(a);
         
          if(to[i].size() == 0) x++;
        }

        to[a] = set<ll>();
      }

     
    }

    cout << x << endl;
    assert(in(x,n+1));
  }

  return 0;
}