提出 #55828915


ソースコード 拡げる

#include <algorithm>
#include <cassert>
#include <iostream>
#include <iterator>
#include <set>
#include <type_traits>
#include <utility>
#include <vector>

namespace noshi91 {

template <class T, class Comp> class partially_retroactive_priority_queue {
public:
  struct return_type {
    std::vector<T> insert;
    std::vector<T> erase;
  };

private:
  int n, m;
  Comp comp;
  struct node {
    int ssum, smin;
    T qmax, dmin;
  };
  std::vector<node> tree;

  const T &min_op(const T &x, const T &y) { return comp(x, y) ? x : y; }
  const T &max_op(const T &x, const T &y) { return comp(x, y) ? y : x; }

  void update_s(int i) {
    while (i /= 2) {
      tree[i].ssum = tree[i << 1].ssum + tree[i << 1 | 1].ssum;
      tree[i].smin = std::min(tree[i << 1].smin,
                              tree[i << 1].ssum + tree[i << 1 | 1].smin);
    }
  }
  void update_q(int i) {
    while (i /= 2)
      tree[i].qmax = max_op(tree[i << 1].qmax, tree[i << 1 | 1].qmax);
  }
  void update_d(int i) {
    while (i /= 2)
      tree[i].dmin = min_op(tree[i << 1].dmin, tree[i << 1 | 1].dmin);
  }

  void incremental_update(const int i, return_type &ret) {
    tree[i].ssum += 1;
    update_s(i);
    int s = tree[1].ssum - 1, k = 1;
    while (k < m) {
      k <<= 1;
      if (tree[k].ssum + tree[k | 1].smin == s) {
        s -= tree[k].ssum;
        k |= 1;
      }
    }
    if (k == m)
      return;
    int c = 0, r = tree.size();
    while (k < r) {
      if (k & 1) {
        if (comp(tree[k].dmin, tree[c].dmin))
          c = k;
        k++;
      }
      k >>= 1, r >>= 1;
    }
    assert(c != 0); // If this assertion fails, there's a bug in this library.
    while (c < m) {
      c <<= 1;
      if (comp(tree[c | 1].dmin, tree[c].dmin))
        c |= 1;
    }
    ret.insert.push_back(tree[c].dmin);
    tree[c].ssum = 0;
    tree[c].qmax = tree[c].dmin;
    tree[c].dmin = tree[0].dmin;
    update_s(c);
    update_q(c);
    update_d(c);
  }

  void decremental_update(const int i, return_type &ret) {
    tree[i].ssum -= 1;
    update_s(i);
    int s = tree[1].ssum, k = 1;
    while (k < m) {
      k <<= 1;
      if (s != tree[k].smin) {
        s -= tree[k].ssum;
        k |= 1;
      }
    }
    int c = 0;
    while (k) {
      if (k & 1) {
        if (comp(tree[c].qmax, tree[--k].qmax))
          c = k;
      }
      k >>= 1;
    }
    if (c == 0)
      return;
    while (c < m) {
      c <<= 1;
      if (comp(tree[c].qmax, tree[c | 1].qmax))
        c |= 1;
    }
    ret.erase.push_back(tree[c].qmax);
    tree[c].ssum = 1;
    tree[c].dmin = tree[c].qmax;
    tree[c].qmax = tree[0].qmax;
    update_s(c);
    update_q(c);
    update_d(c);
  }

public:
  partially_retroactive_priority_queue(int n, Comp comp, T min, T max)
      : n(n), m(1), comp(std::move(comp)), tree() {
    assert(comp(min, max));
    assert(!comp(min, min));
    assert(!comp(max, max));
    while (m < n + 1)
      m *= 2;
    tree.resize(2 * m, node{0, 0, min, max});
    tree[0].qmax = min;
    tree[0].dmin = max;
  }
  return_type set_push(int i, T x) {
    assert(0 <= i && i < n);
    assert(comp(tree[0].qmax, x) && comp(x, tree[0].dmin));
    auto ret = set_no_op(i);
    i += m;
    tree[i].dmin = x;
    update_d(i);
    incremental_update(i, ret);
    return ret;
  }
  return_type set_pop(int i) {
    assert(0 <= i && i < n);
    auto ret = set_no_op(i);
    i += m;
    decremental_update(i, ret);
    return ret;
  }
  return_type set_no_op(int i) {
    assert(0 <= i && i < n);
    return_type ret;
    i += m;
    if (tree[i].ssum == -1) {
      incremental_update(i, ret);
    } else if (comp(tree[0].qmax, tree[i].qmax)) {
      ret.erase.push_back(tree[i].qmax);
      tree[i].qmax = tree[0].qmax;
      update_q(i);
    } else if (comp(tree[i].dmin, tree[0].dmin)) {
      tree[i].dmin = tree[0].dmin;
      update_d(i);
      decremental_update(i, ret);
    }
    return ret;
  }
  void dump() {
    std::cerr << "\n##### dump partially_retroactive_priority_queue #####\n\n";
    std::multiset<T, Comp> set(comp);
    for (int i = 0; i < n; i++) {
      std::cerr << i << "-th op: ";
      const auto &v = tree[i + m];
      if (v.ssum == -1) {
        std::cerr << "pop";
        if (!set.empty())
          set.erase(std::prev(set.end()));
      } else if (comp(tree[0].qmax, v.qmax)) {
        std::cerr << "push " << v.qmax;
        set.insert(v.qmax);
      } else if (comp(v.dmin, tree[0].dmin)) {
        std::cerr << "push " << v.dmin;
        set.insert(v.dmin);
      } else {
        std::cerr << "no_op";
      }
      std::cerr << "\n{{";
      bool first = true;
      for (const T &x : set) {
        if (!std::exchange(first, false))
          std::cerr << ",";
        std::cerr << " " << x;
      }
      std::cerr << " }}\n";
    }
    std::cerr << "\n##### end #####\n\n";
    std::cerr.flush();
  }
};

} // namespace noshi91

#include <bits/stdc++.h>

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);

  int N, Q;
  std::cin >> N >> Q;
  std::vector<int> D(N), P(N);
  for (auto &e : D)
    std::cin >> e, e--;
  for (auto &e : P)
    std::cin >> e;
  struct query_type {
    int c, x, y;
  };
  std::vector<query_type> qs(Q);
  for (auto &[c, x, y] : qs)
    std::cin >> c >> x >> y, c--, x--;

  std::vector<int> count(N, 1);
  for (const auto &e : D)
    count[e]++;
  for (const auto &[c, x, y] : qs)
    count[x]++;
  for (int i = N; --i;)
    count[i - 1] += count[i];

  noshi91::partially_retroactive_priority_queue<int, std::less<int>> prpq(
      count[0], {}, 0, int(1e9) + 1);
  for (int i = 0; i < N; i++) {
    prpq.set_pop(--count[i]);
  }

  long long ans = 0;
  const auto update = [&](const auto &res) {
    for (const auto &e : res.insert)
      ans -= e;
    for (const auto &e : res.erase)
      ans += e;
  };

  std::vector<int> idx(N);
  for (int i = 0; i < N; i++) {
    idx[i] = --count[D[i]];
    update(prpq.set_push(idx[i], P[i]));
    ans += P[i];
  }

  for (const auto &[c, x, y] : qs) {
    update(prpq.set_no_op(idx[c]));
    ans -= P[c];
    idx[c] = --count[x];
    P[c] = y;
    update(prpq.set_push(idx[c], y));
    ans += P[c];
    std::cout << ans << "\n";
  }

  return 0;
}

提出情報

提出日時
問題 G - Dynamic Scheduling
ユーザ noshi91
言語 C++ 20 (gcc 12.2)
得点 675
コード長 6445 Byte
結果 AC
実行時間 157 ms
メモリ 22440 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 675 / 675
結果
AC × 3
AC × 89
セット名 テストケース
Sample 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt
All 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 01_n_small_00.txt, 01_n_small_01.txt, 01_n_small_02.txt, 01_n_small_03.txt, 01_n_small_04.txt, 01_n_small_05.txt, 01_n_small_06.txt, 01_n_small_07.txt, 01_n_small_08.txt, 01_n_small_09.txt, 01_n_small_10.txt, 01_n_small_11.txt, 01_n_small_12.txt, 01_n_small_13.txt, 01_n_small_14.txt, 01_n_small_15.txt, 01_n_small_16.txt, 01_n_small_17.txt, 01_n_small_18.txt, 01_n_small_19.txt, 01_n_small_20.txt, 02_q_small_00.txt, 02_q_small_01.txt, 02_q_small_02.txt, 02_q_small_03.txt, 02_q_small_04.txt, 03_n_mul_q_small_00.txt, 03_n_mul_q_small_01.txt, 03_n_mul_q_small_02.txt, 03_n_mul_q_small_03.txt, 03_n_mul_q_small_04.txt, 04_random_00.txt, 04_random_01.txt, 04_random_02.txt, 04_random_03.txt, 04_random_04.txt, 04_random_05.txt, 04_random_06.txt, 04_random_07.txt, 04_random_08.txt, 04_random_09.txt, 04_random_10.txt, 04_random_11.txt, 05_random_max_1_00.txt, 05_random_max_1_01.txt, 05_random_max_1_02.txt, 05_random_max_1_03.txt, 05_random_max_1_04.txt, 06_random_max_2_00.txt, 06_random_max_2_01.txt, 06_random_max_2_02.txt, 06_random_max_2_03.txt, 06_random_max_2_04.txt, 07_q_2_power_00.txt, 07_q_2_power_01.txt, 07_q_2_power_02.txt, 07_q_2_power_03.txt, 07_q_2_power_04.txt, 08_p_small_difference_00.txt, 08_p_small_difference_01.txt, 08_p_small_difference_02.txt, 08_p_small_difference_03.txt, 08_p_small_difference_04.txt, 08_p_small_difference_05.txt, 08_p_small_difference_06.txt, 08_p_small_difference_07.txt, 08_p_small_difference_08.txt, 08_p_small_difference_09.txt, 09_turnaround_00.txt, 09_turnaround_01.txt, 09_turnaround_02.txt, 09_turnaround_03.txt, 09_turnaround_04.txt, 09_turnaround_05.txt, 09_turnaround_06.txt, 09_turnaround_07.txt, 09_turnaround_08.txt, 09_turnaround_09.txt, 09_turnaround_10.txt, 09_turnaround_11.txt, 09_turnaround_12.txt, 09_turnaround_13.txt, 09_turnaround_14.txt, 10_corner_00.txt, 10_corner_01.txt, 10_corner_02.txt
ケース名 結果 実行時間 メモリ
00_sample_00.txt AC 1 ms 3420 KiB
00_sample_01.txt AC 1 ms 3436 KiB
00_sample_02.txt AC 1 ms 3448 KiB
01_n_small_00.txt AC 1 ms 3448 KiB
01_n_small_01.txt AC 38 ms 8320 KiB
01_n_small_02.txt AC 61 ms 8312 KiB
01_n_small_03.txt AC 45 ms 8340 KiB
01_n_small_04.txt AC 57 ms 8296 KiB
01_n_small_05.txt AC 62 ms 8232 KiB
01_n_small_06.txt AC 48 ms 8268 KiB
01_n_small_07.txt AC 55 ms 8336 KiB
01_n_small_08.txt AC 61 ms 8284 KiB
01_n_small_09.txt AC 62 ms 8352 KiB
01_n_small_10.txt AC 50 ms 8276 KiB
01_n_small_11.txt AC 53 ms 8264 KiB
01_n_small_12.txt AC 59 ms 8352 KiB
01_n_small_13.txt AC 62 ms 8448 KiB
01_n_small_14.txt AC 62 ms 8316 KiB
01_n_small_15.txt AC 51 ms 8348 KiB
01_n_small_16.txt AC 59 ms 8344 KiB
01_n_small_17.txt AC 73 ms 8268 KiB
01_n_small_18.txt AC 68 ms 8300 KiB
01_n_small_19.txt AC 66 ms 8328 KiB
01_n_small_20.txt AC 54 ms 8372 KiB
02_q_small_00.txt AC 50 ms 12776 KiB
02_q_small_01.txt AC 45 ms 12792 KiB
02_q_small_02.txt AC 48 ms 12780 KiB
02_q_small_03.txt AC 51 ms 12776 KiB
02_q_small_04.txt AC 51 ms 12760 KiB
03_n_mul_q_small_00.txt AC 3 ms 3416 KiB
03_n_mul_q_small_01.txt AC 3 ms 3560 KiB
03_n_mul_q_small_02.txt AC 2 ms 3388 KiB
03_n_mul_q_small_03.txt AC 3 ms 3508 KiB
03_n_mul_q_small_04.txt AC 3 ms 3500 KiB
04_random_00.txt AC 95 ms 13276 KiB
04_random_01.txt AC 126 ms 22100 KiB
04_random_02.txt AC 76 ms 12940 KiB
04_random_03.txt AC 126 ms 22268 KiB
04_random_04.txt AC 62 ms 12776 KiB
04_random_05.txt AC 112 ms 22004 KiB
04_random_06.txt AC 97 ms 12752 KiB
04_random_07.txt AC 133 ms 22296 KiB
04_random_08.txt AC 48 ms 8340 KiB
04_random_09.txt AC 60 ms 13012 KiB
04_random_10.txt AC 109 ms 13300 KiB
04_random_11.txt AC 132 ms 22308 KiB
05_random_max_1_00.txt AC 133 ms 22268 KiB
05_random_max_1_01.txt AC 132 ms 22268 KiB
05_random_max_1_02.txt AC 128 ms 22364 KiB
05_random_max_1_03.txt AC 131 ms 22276 KiB
05_random_max_1_04.txt AC 126 ms 22272 KiB
06_random_max_2_00.txt AC 131 ms 22276 KiB
06_random_max_2_01.txt AC 130 ms 22224 KiB
06_random_max_2_02.txt AC 130 ms 22256 KiB
06_random_max_2_03.txt AC 131 ms 22280 KiB
06_random_max_2_04.txt AC 131 ms 22352 KiB
07_q_2_power_00.txt AC 89 ms 21724 KiB
07_q_2_power_01.txt AC 85 ms 21752 KiB
07_q_2_power_02.txt AC 81 ms 21744 KiB
07_q_2_power_03.txt AC 84 ms 21776 KiB
07_q_2_power_04.txt AC 91 ms 21748 KiB
08_p_small_difference_00.txt AC 133 ms 22224 KiB
08_p_small_difference_01.txt AC 131 ms 22224 KiB
08_p_small_difference_02.txt AC 123 ms 22328 KiB
08_p_small_difference_03.txt AC 136 ms 22440 KiB
08_p_small_difference_04.txt AC 131 ms 22224 KiB
08_p_small_difference_05.txt AC 127 ms 22292 KiB
08_p_small_difference_06.txt AC 134 ms 22344 KiB
08_p_small_difference_07.txt AC 129 ms 22248 KiB
08_p_small_difference_08.txt AC 126 ms 22260 KiB
08_p_small_difference_09.txt AC 124 ms 22332 KiB
09_turnaround_00.txt AC 150 ms 22268 KiB
09_turnaround_01.txt AC 145 ms 22280 KiB
09_turnaround_02.txt AC 131 ms 22296 KiB
09_turnaround_03.txt AC 124 ms 22252 KiB
09_turnaround_04.txt AC 122 ms 22232 KiB
09_turnaround_05.txt AC 157 ms 22256 KiB
09_turnaround_06.txt AC 154 ms 22332 KiB
09_turnaround_07.txt AC 150 ms 22336 KiB
09_turnaround_08.txt AC 139 ms 22340 KiB
09_turnaround_09.txt AC 131 ms 22248 KiB
09_turnaround_10.txt AC 157 ms 22300 KiB
09_turnaround_11.txt AC 154 ms 22256 KiB
09_turnaround_12.txt AC 154 ms 22248 KiB
09_turnaround_13.txt AC 154 ms 22284 KiB
09_turnaround_14.txt AC 146 ms 22308 KiB
10_corner_00.txt AC 74 ms 22292 KiB
10_corner_01.txt AC 129 ms 22224 KiB
10_corner_02.txt AC 54 ms 13328 KiB