結果

問題 No.2292 Interval Union Find
ユーザー KumaTachiRenKumaTachiRen
提出日時 2023-05-05 22:32:50
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 189 ms / 5,000 ms
コード長 3,317 bytes
コンパイル時間 4,064 ms
コンパイル使用メモリ 270,740 KB
実行使用メモリ 12,928 KB
最終ジャッジ日時 2024-05-02 17:22:03
合計ジャッジ時間 12,863 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 2 ms
5,376 KB
testcase_03 AC 2 ms
5,376 KB
testcase_04 AC 63 ms
5,376 KB
testcase_05 AC 101 ms
5,376 KB
testcase_06 AC 68 ms
5,376 KB
testcase_07 AC 105 ms
5,376 KB
testcase_08 AC 111 ms
5,376 KB
testcase_09 AC 104 ms
5,376 KB
testcase_10 AC 87 ms
5,376 KB
testcase_11 AC 76 ms
5,376 KB
testcase_12 AC 99 ms
5,376 KB
testcase_13 AC 70 ms
5,376 KB
testcase_14 AC 76 ms
5,376 KB
testcase_15 AC 80 ms
5,376 KB
testcase_16 AC 76 ms
5,376 KB
testcase_17 AC 93 ms
5,376 KB
testcase_18 AC 149 ms
12,928 KB
testcase_19 AC 182 ms
12,800 KB
testcase_20 AC 189 ms
12,800 KB
testcase_21 AC 160 ms
8,960 KB
testcase_22 AC 154 ms
8,832 KB
testcase_23 AC 160 ms
8,960 KB
testcase_24 AC 163 ms
8,960 KB
testcase_25 AC 161 ms
8,960 KB
testcase_26 AC 165 ms
8,832 KB
testcase_27 AC 163 ms
8,832 KB
testcase_28 AC 149 ms
8,832 KB
testcase_29 AC 164 ms
8,960 KB
testcase_30 AC 159 ms
8,960 KB
testcase_31 AC 163 ms
8,960 KB
testcase_32 AC 164 ms
8,832 KB
testcase_33 AC 159 ms
8,960 KB
testcase_34 AC 153 ms
8,832 KB
testcase_35 AC 164 ms
8,960 KB
testcase_36 AC 162 ms
8,832 KB
testcase_37 AC 159 ms
8,960 KB
testcase_38 AC 167 ms
8,960 KB
testcase_39 AC 158 ms
8,832 KB
testcase_40 AC 160 ms
8,960 KB
testcase_41 AC 47 ms
5,376 KB
testcase_42 AC 46 ms
5,376 KB
testcase_43 AC 51 ms
5,376 KB
testcase_44 AC 57 ms
5,376 KB
testcase_45 AC 57 ms
5,376 KB
testcase_46 AC 62 ms
5,376 KB
testcase_47 AC 67 ms
5,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#include <atcoder/all>

using namespace std;
using namespace atcoder;

struct Fast
{
  Fast()
  {
    std::cin.tie(0);
    ios::sync_with_stdio(false);
  }
} fast;

#define rep(i, a, b) for (int i = (a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (a); i--)
#define ll long long

template <typename T>
bool chmax(T &a, const T &b)
{
  if (a < b)
  {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
bool chmin(T &a, const T &b)
{
  if (a > b)
  {
    a = b;
    return true;
  }
  return false;
}

// https://satanic0258.github.io/snippets/data-structure/SegmentMap.html
// Description: 区間をsetで管理するデータ構造(なお実装はmap).各クエリO(log区間数).

// #### attention! : [l, r] ( include r, not [l, r) )
class SegmentMap : public std::map<signed, signed>
{
private:
  bool flagToMergeAdjacentSegment;

public:
  // if merge [l, c] and [c+1, r], set flagToMergeAdjacentSegment to true
  SegmentMap(bool flagToMergeAdjacentSegment) : flagToMergeAdjacentSegment(flagToMergeAdjacentSegment) {}
  // __exist -> iterator pair(l, r) (contain p)
  // noexist -> map.end()
  auto get(signed p) const
  {
    auto it = upper_bound(p);
    if (it == begin() || (--it)->second < p)
      return end();
    return it;
  }
  // insert segment [l, r]
  void insert(signed l, signed r)
  {
    auto itl = upper_bound(l), itr = upper_bound(r + flagToMergeAdjacentSegment);
    if (itl != begin())
    {
      if ((--itl)->second < l - flagToMergeAdjacentSegment)
        ++itl;
    }
    if (itl != itr)
    {
      l = std::min(l, itl->first);
      r = std::max(r, std::prev(itr)->second);
      erase(itl, itr);
    }
    (*this)[l] = r;
  }
  // remove segment [l, r]
  void remove(signed l, signed r)
  {
    auto itl = upper_bound(l), itr = upper_bound(r);
    if (itl != begin())
    {
      if ((--itl)->second < l)
        ++itl;
    }
    if (itl == itr)
      return;
    int tl = std::min(l, itl->first), tr = std::max(r, std::prev(itr)->second);
    erase(itl, itr);
    if (tl < l)
      (*this)[tl] = l - 1;
    if (r < tr)
      (*this)[r + 1] = tr;
  }
  // Is p and q in same segment?
  bool same(signed p, signed q) const
  {
    const auto &&it = get(p);
    return it != end() && it->first <= q && q <= it->second;
  }
  bool contains(signed x) const
  {
    const auto &&it = get(x);
    return it != end() && it->first <= x && x <= it->second;
  }
};

int main()
{
  int n, q;
  cin >> n >> q;
  SegmentMap s(false);
  while (q--)
  {
    int type;
    cin >> type;
    if (type == 1)
    {
      int l, r;
      cin >> l >> r;
      l--;
      r--;
      s.insert(l, r);
    }
    if (type == 2)
    {
      int l, r;
      cin >> l >> r;
      l--;
      r--;
      s.remove(l + 1, r - 1);
    }
    if (type == 3)
    {
      int u, v;
      cin >> u >> v;
      u--;
      v--;
      int ans = -1;
      if (u == v)
      {
        ans = 1;
      }
      else
      {
        ans = s.same(u, v) ? 1 : 0;
      }
      cout << ans << "\n";
    }
    if (type == 4)
    {
      int v;
      cin >> v;
      v--;
      if (s.contains(v))
      {
        auto it = s.get(v);
        cout << (it->second - it->first + 1) << "\n";
      }
      else
      {
        cout << 1 << "\n";
      }
    }
  }
}
0