結果

問題 No.1000 Point Add and Array Add
ユーザー _____TAB__________TAB_____
提出日時 2020-02-28 21:50:41
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 321 ms / 2,000 ms
コード長 4,831 bytes
コンパイル時間 1,034 ms
コンパイル使用メモリ 85,760 KB
実行使用メモリ 16,752 KB
最終ジャッジ日時 2024-10-13 17:16:18
合計ジャッジ時間 5,191 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 2 ms
5,248 KB
testcase_04 AC 2 ms
5,248 KB
testcase_05 AC 2 ms
5,248 KB
testcase_06 AC 2 ms
5,248 KB
testcase_07 AC 2 ms
5,248 KB
testcase_08 AC 2 ms
5,248 KB
testcase_09 AC 2 ms
5,248 KB
testcase_10 AC 2 ms
5,248 KB
testcase_11 AC 2 ms
5,248 KB
testcase_12 AC 4 ms
5,248 KB
testcase_13 AC 3 ms
5,248 KB
testcase_14 AC 4 ms
5,248 KB
testcase_15 AC 4 ms
5,248 KB
testcase_16 AC 225 ms
14,080 KB
testcase_17 AC 190 ms
10,468 KB
testcase_18 AC 321 ms
16,744 KB
testcase_19 AC 311 ms
16,752 KB
testcase_20 AC 269 ms
16,568 KB
testcase_21 AC 312 ms
16,748 KB
testcase_22 AC 301 ms
16,620 KB
testcase_23 AC 312 ms
16,488 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
using namespace std;


template <
  typename Monoid,
  typename Container = std::vector<typename Monoid::first_type>,
  typename SubContainer = std::vector<typename Monoid::second_type>
>
class segment_tree {
public:
  using first_type = typename Monoid::first_type;
  using second_type = typename Monoid::second_type;
  using value_type = first_type;
  using binary_operation = typename Monoid::binary_operation;
  using external_binary_operation = typename Monoid::external_binary_operation;
  using merge_operation = typename Monoid::merge_operation;
  using container = Container;
  using sub_container = SubContainer;

private:
  size_t M_base_size;
  binary_operation M_op1;
  external_binary_operation M_op2;
  merge_operation M_op3;
  container M_c;
  sub_container M_d;  // deferred

  void M_build(size_t i) {
    while (i > 1) {
      i >>= 1;
      M_c[i] = M_op2(M_op1(M_c[i<<1|0], M_c[i<<1|1]), M_d[i]);
    }
  }

  void M_resolve(size_t i) {
    size_t h = (sizeof(long long) * CHAR_BIT) - __builtin_clzll(M_base_size*2);
    for (size_t s = h; s > 0; --s) {
      size_t p = i >> s;
      if (M_d[p] != M_op3.identity) {
        M_apply(p<<1|0, M_d[p]);
        M_apply(p<<1|1, M_d[p]);
        M_d[p] = M_op3.identity;
      }
    }
  }

  void M_apply(size_t i, second_type const& x) {
    M_c[i] = M_op2(M_c[i], x);
    if (i < M_base_size) M_d[i] = M_op3(M_d[i], x);
  }

public:
  segment_tree() = default;
  segment_tree(segment_tree const&) = default;
  segment_tree(segment_tree&&) = default;

  segment_tree(size_t n, first_type const& x = binary_operation().identity):
    M_base_size(n),
    M_op1(binary_operation()),
    M_op2(external_binary_operation()),
    M_op3(merge_operation()),
    M_c(n+n, x), M_d(n, M_op3.identity)
  {
    for (size_t i = n; i--;)
      M_c[i] = M_op1(M_c[i<<1|0], M_c[i<<1|1]);
  }

  template <typename InputIt>
  segment_tree(InputIt first, InputIt last):
    M_base_size(std::distance(first, last)),
    M_op1(binary_operation()),
    M_op2(external_binary_operation()),
    M_op3(merge_operation()),
    M_c(M_base_size*2), M_d(M_base_size, M_op3.identity)
  {
    for (size_t i = M_base_size; first != last; ++i)
      M_c[i] = *first++;
    for (size_t i = M_base_size; i--;)
      M_c[i] = M_op1(M_c[i<<1|0], M_c[i<<1|1]);
  }

  segment_tree& operator =(segment_tree const&) = default;
  segment_tree& operator =(segment_tree&&) = default;

  void modify(size_t l, size_t r, second_type const& x) {
    if (l == r) return;  // for [n, n)
    l += M_base_size;
    r += M_base_size;
    size_t l0 = l;
    size_t r0 = r;
    while (l < r) {
      if (l & 1) M_apply(l++, x);
      if (r & 1) M_apply(--r, x);
      l >>= 1;
      r >>= 1;
    }
    M_build(l0);
    M_build(r0-1);
  }

  first_type accumulate(size_t l, size_t r) {
    first_type resl = M_op1.identity;
    first_type resr = resl;
    if (l == r) return resl;  // for [n, n)

    l += M_base_size;
    r += M_base_size;
    M_resolve(l);
    M_resolve(r-1);
    while (l < r) {
      if (l & 1) resl = M_op1(resl, M_c[l++]);
      if (r & 1) resr = M_op1(M_c[--r], resr);
      l >>= 1;
      r >>= 1;
    }
    return M_op1(resl, resr);
  }

  first_type operator [](size_t i) {
    i += M_base_size;
    M_resolve(i);
    return M_c[i];
  }
};

template <typename Tp>
struct range_sum_range_add {
  using first_type = std::pair<Tp, Tp>;
  using second_type = Tp;
  struct binary_operation {
    first_type identity{0, 1};
    first_type operator ()(first_type const& x, first_type const& y) const {
      return {x.first+y.first, x.second+y.second};
    }
  };
  struct external_binary_operation {
    first_type operator ()(first_type const& x, second_type const& y) const {
      // a+b(x+c) = (a+bc)+bx
      return {x.first+x.second*y, x.second};
    }
  };
  struct merge_operation {
    second_type identity{0};
    second_type operator ()(second_type const& x, second_type const& y) const {
      return x+y;
    }
  };
};

struct query {
  char c;
  int x, y;
  query(char c, int x, int y) : c(c), x(x), y(y) {}
};

int main(){
  int N, q;
  cin >> N >> q;
  vector<long long> A(N);
  for(int i = 0; i < N; ++i) cin >> A[i];
  vector<query> Q;
  for(int i = 0; i < q; ++i){
    char c;
    int x, y;
    cin >> c >> x >> y;
    --x;
    Q.emplace_back(c,x,y);
  }
  reverse(Q.begin(), Q.end());
  segment_tree<range_sum_range_add<long long>> st(N);
  vector<long long> B(N);
  for(auto qq : Q){
    if(qq.c == 'A'){
      long long cnt = st.accumulate(qq.x,qq.x+1).first;
      B[qq.x] += cnt*qq.y;
    }else{
      st.modify(qq.x,qq.y,1);
    }
  }
  for(int i = 0; i < N; ++i){
    B[i] += st.accumulate(i,i+1).first*A[i];
  }
  for(int i = 0; i < N; ++i){
    cout << B[i] << (i+1 < N ? " " : "\n");
  }
}
0