結果

問題 No.833 かっこいい電車
ユーザー ei1333333ei1333333
提出日時 2019-05-24 21:40:18
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
RE  
実行時間 -
コード長 4,798 bytes
コンパイル時間 3,023 ms
コンパイル使用メモリ 237,276 KB
実行使用メモリ 25,948 KB
最終ジャッジ日時 2024-07-02 03:39:34
合計ジャッジ時間 10,914 ms
ジャッジサーバーID
(参考情報)
judge4 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 166 ms
25,848 KB
testcase_01 AC 2 ms
5,376 KB
testcase_02 AC 2 ms
5,376 KB
testcase_03 AC 3 ms
5,376 KB
testcase_04 AC 2 ms
5,376 KB
testcase_05 AC 2 ms
5,376 KB
testcase_06 AC 2 ms
5,376 KB
testcase_07 AC 2 ms
5,376 KB
testcase_08 AC 2 ms
5,376 KB
testcase_09 AC 2 ms
5,376 KB
testcase_10 RE -
testcase_11 RE -
testcase_12 RE -
testcase_13 RE -
testcase_14 RE -
testcase_15 RE -
testcase_16 AC 25 ms
6,016 KB
testcase_17 RE -
testcase_18 RE -
testcase_19 RE -
testcase_20 AC 6 ms
5,376 KB
testcase_21 RE -
testcase_22 RE -
testcase_23 RE -
testcase_24 RE -
testcase_25 RE -
testcase_26 RE -
testcase_27 RE -
testcase_28 RE -
testcase_29 RE -
testcase_30 AC 44 ms
14,096 KB
testcase_31 AC 166 ms
25,948 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<bits/stdc++.h>

using namespace std;

using int64 = long long;
const int mod = 1e9 + 7;

const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;

struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} iosetup;


template< typename T1, typename T2 >
ostream &operator<<(ostream &os, const pair< T1, T2 > &p) {
  os << p.first << " " << p.second;
  return os;
}

template< typename T1, typename T2 >
istream &operator>>(istream &is, pair< T1, T2 > &p) {
  is >> p.first >> p.second;
  return is;
}

template< typename T >
ostream &operator<<(ostream &os, const vector< T > &v) {
  for(int i = 0; i < (int) v.size(); i++) {
    os << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return os;
}

template< typename T >
istream &operator>>(istream &is, vector< T > &v) {
  for(T &in : v) is >> in;
  return is;
}

template< typename T1, typename T2 >
inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }

template< typename T1, typename T2 >
inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }

template< typename T = int64 >
vector< T > make_v(size_t a) {
  return vector< T >(a);
}

template< typename T, typename... Ts >
auto make_v(size_t a, Ts... ts) {
  return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));
}

template< typename T, typename V >
typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {
  t = v;
}

template< typename T, typename V >
typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {
  for(auto &e : t) fill_v(e, v);
}

using edge = pair< int, int >;

struct UnionFind {
  vector< int64 > data;
  stack< pair< int, int > > st;

  UnionFind() {}

  UnionFind(int sz) {
    data.assign(sz, -1);
  }

  bool unite(int x, int y) {
    x = find(x), y = find(y);
    st.emplace(x, data[x]);
    st.emplace(y, data[y]);
    if(x == y) return (false);
    if(data[x] > data[y]) swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return (true);
  }

  int find(int k) {
    if(data[k] < 0) return (k);
    return (find(data[k]));
  }

  int size(int k) {
    return (-data[find(k)]);
  }

  void undo() {
    data[st.top().first] = st.top().second;
    st.pop();
    data[st.top().first] = st.top().second;
    st.pop();
  }
};


UnionFind uf;

struct Dynamic_connectivity {
  int n, sz;
  vector< vector< edge > > edges;

  vector< pair< pair< int, int >, edge > > pending;
  map< edge, int > cnt, appear;

  Dynamic_connectivity(int nn, int q) : n(q) // (2018-03-21修正)
  {
    uf = UnionFind(nn);
    sz = 1;
    while(sz < n) sz <<= 1;
    edges.resize(2 * sz - 1);
  }

  void insert(int idx, edge e) {
    if(e.first > e.second) swap(e.first, e.second);
    if(cnt[e]++ == 0) appear[e] = idx;
  }

  void erase(int idx, edge e) {
    if(e.first > e.second) swap(e.first, e.second);
    if(--cnt[e] == 0) pending.emplace_back(make_pair(appear[e], idx), e);
  }

  void add(int a, int b, const edge &e, int k, int l, int r) {
    if(r <= a || b <= l) return;
    if(a <= l && r <= b) {
      edges[k].emplace_back(e);
      return;
    }
    add(a, b, e, 2 * k + 1, l, (l + r) >> 1);
    add(a, b, e, 2 * k + 2, (l + r) >> 1, r);
  }

  void add(int a, int b, const edge &e) {
    add(a, b, e, 0, 0, sz);
  }

  void build() {
    for(auto &p : cnt) {
      if(p.second > 0) pending.emplace_back(make_pair(appear[p.first], sz), p.first);
    }
    for(auto &s : pending) {
      add(s.first.first, s.first.second, s.second);
    }
  }

  void execute(const function< void(int) > &f, int k = 0) {
    for(auto &e : edges[k]) {
      int a, b;
      tie(a, b) = e;
      uf.unite(a, b);
    }
    if(k < sz - 1) {
      execute(f, 2 * k + 1);
      execute(f, 2 * k + 2);
    } else if(k - (sz - 1) < n) {
      int query_index = k - (sz - 1);
      f(query_index);
    }
    for(auto &e : edges[k]) {
      uf.undo();
    }
  }
};

int main() {
  int N, Q;
  cin >> N >> Q;
  vector< int > A(N);
  cin >> A;
  Dynamic_connectivity dc(N + Q, Q);
  for(int i = 0; i < N; i++) {
    uf.data[i] = -A[i];
  }
  int ptr = N;
  set< pair< int, int > > st;
  vector< int > C(Q, -1);
  for(int i = 0; i < Q; i++) {
    int a, b;
    cin >> a >> b;
    --b;
    int c = b + 1;
    if(a == 1) {
      if(st.count({b, c})) continue;
      st.emplace(b, c);
      dc.insert(i, edge(b, c));
    } else if(a == 2) {
      if(!st.count({b, c})) continue;
      st.erase({b, c});
      dc.erase(i, edge(b, c));
    } else if(a == 3) {
      dc.insert(i, edge(b, ptr++));
    } else {
      C[i] = b;
    }
  }
  dc.build();
  auto f = [&](int k) {
    if(~C[k]) {
      cout << uf.size(C[k]) << endl;
    }
  };
  dc.execute(f);
  // いやいきりました
}

0