結果
| 問題 | No.789 範囲の合計 | 
| コンテスト | |
| ユーザー |  | 
| 提出日時 | 2024-05-30 01:29:59 | 
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) | 
| 結果 | 
                                MLE
                                 
                             | 
| 実行時間 | - | 
| コード長 | 8,680 bytes | 
| コンパイル時間 | 6,822 ms | 
| コンパイル使用メモリ | 398,516 KB | 
| 実行使用メモリ | 227,584 KB | 
| 最終ジャッジ日時 | 2024-12-20 21:05:30 | 
| 合計ジャッジ時間 | 11,851 ms | 
| ジャッジサーバーID (参考情報) | judge3 / judge4 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| other | AC * 8 MLE * 7 | 
ソースコード
#line 1 "test/yukicoder/789__dynamic_seg.test.cpp"
#define PROBLEM "https://yukicoder.me/problems/no/789"
#line 2 "common/util.hpp"
#line 2 "common/alias.hpp"
#include <boost/multiprecision/cpp_int.hpp>
#include <bits/stdc++.h>
using namespace std;
// using namespace std::views;
// using namespace boost::multiprecision;
// --- 型エイリアス ---
using ll = long long;
using ull = unsigned long long;
template <typename T> using vec = vector<T>;
template <typename T> using vvec = vector<vector<T>>;
template <typename T> using vvvec = vector<vector<vector<T>>>;
template <typename T> using p_queue = priority_queue<T>;
template <typename T> using rp_queue = priority_queue<T, vec<T>, greater<T>>;
using bint = boost::multiprecision::cpp_int;
// --- 黒魔術 ---
#define int ll
// --- 制御マクロ ---
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define all(v) begin(v), end(v)
// #define BIT(n) (1LL << (n))
#define MAX(type) numeric_limits<type>::max()
#define MIN(type) numeric_limits<type>::min()
#define yes cout << "Yes" << endl
#define no cout << "No" << endl
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
// --- 定数 ---
constexpr ll INF = 1LL << 60;
// constexpr ll INF = numeric_limits<ll>::max();
inline signed bit_width(ll x) { return bit_width((ull)x); }
inline ull bit_ceil(ll x) { return bit_ceil((ull)x); }
#line 2 "common/concepts.hpp"
#line 4 "common/concepts.hpp"
template <class T>
concept addable = requires(T a, T b) {
  { a + b } -> convertible_to<T>;
};
#line 5 "common/util.hpp"
// --- Utils ---
// 二分探索
template <typename T>
inline T bin_search(T ok, T ng, const function<bool(T)> is_ok) {
  assert(is_ok(ok));
  assert(!is_ok(ng));
  assert(ok < ng);
  while (abs(ok - ng) > 1) {
    T mid = (ok + ng) / 2;
    if (is_ok(mid))
      ok = mid;
    else
      ng = mid;
  }
  return ok;
}
// 順列全探索
inline void rep_perm(int n, function<void(vec<int> &)> f) {
  vec<int> v(n);
  iota(v.begin(), v.end(), 0);
  do {
    f(v);
  } while (next_permutation(v.begin(), v.end()));
}
inline void rep_bit(int n, function<void(int)> f) { rep(i, 1LL << n) f(i); }
// 配列 to string
template <typename T> inline string join(const vec<T> &v, string sep = " ") {
  string res = "";
  rep(i, v.size()) res += to_string(v[i]) + (i == v.size() - 1 ? "" : sep);
  return res;
}
template <typename T>
inline void join_out(ostream &os, const vec<T> &v, string sep = " ",
                     string end = "\n") {
  int n = v.size();
  rep(i, n) os << v[i] << (i == n - 1 ? end : sep);
}
template <typename T>
inline void transform(vec<T> &src, function<void(T &)> f) {
  for (auto &val : src)
    f(val);
}
// ベース指定ceil
inline ll ceil(ll x, ll base) { return (x + base - 1) / base * base; }
// ベース指定floor
inline ll floor(ll x, ll base) { return x / base * base; }
// 合計値を求める
// ll sum(const vec<ll> &v) { return accumulate(all(v), 0LL); }
template <addable T> T sum(const vec<T> &v) { return accumulate(all(v), T()); }
// 可変引数min
template <class... T> auto min(T... a) {
  return min(initializer_list<common_type_t<T...>>{a...});
}
// 可変引数max
template <class... T> auto max(T... a) {
  return max(initializer_list<common_type_t<T...>>{a...});
}
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
// 3項間不等式
// 広義単調増加
inline bool is_increasing(int x, int y, int z) { return x <= y && y <= z; }
// 半開区間[x, z)にyが含まれるか?
inline bool is_contained(int x, int y, int z) { return x <= y && y < z; }
// 頂点(x, y)が範囲に含まれるか
inline bool is_contained(int H, int W, int x, int y) {
  return is_contained(0, x, H) && is_contained(0, y, W);
}
// rootに対し、aとbが同じ側にあるか (=は含まない)
inline bool is_same_side(int root, int a, int b) {
  return (root < a) == (root < b);
}
// vector継承にする?
template <typename T> struct vec_accumulate : public vec<T> {
  explicit vec_accumulate(vec<T> &v) : vec<T>(v.size()) {
    assert(v.size() > 0);
    this->at(0) = v[0];
    for (int i = 1; i < v.size(); ++i)
      this->at(i) = this->at(i - 1) + v[i];
  }
  // [0, i]の和
  // なので、-1 <= i < size()
  T operator[](int i) {
    assert(is_contained(-1, i, this->size()));
    if (i == -1)
      return T();
    return this->at(i);
  }
};
// vector func
template <typename T> inline void unique_erase(vec<T> &v) {
  sort(all(v));
  v.erase(unique(all(v)), v.end());
}
void io_setup() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << std::fixed << std::setprecision(15);
}
#line 2 "datastructure/dynamic-segment-tree.hpp"
#line 4 "datastructure/dynamic-segment-tree.hpp"
/**
 * @brief セグメント木
 *
 * @tparam T ノードの型
 */
template <typename T> struct DynamicSegmentTree {
private:
  /// 単位元
  T e;
  /// 演算
  function<T(T, T)> op;
  /// 要素数
  int n;
  /// ノードの構造体
  struct Node {
    /// ノードの値
    T val;
    /// 初期化用の値
    T e;
    /// 親ノード, 左の子ノード, 右の子ノード
    Node *p, *l_child, *r_child;
    /// ノードの範囲
    int l, r;
    Node(T val, T e, int l, int r) :
      val(val), e(e),
      p(nullptr), l_child(nullptr), r_child(nullptr),
      l(l), r(r) {}
    Node(T val, Node *p, bool child_index) :
      val(val), e(p->e),
      p(p), l_child(nullptr), r_child(nullptr),
      l(!child_index ? p->l : p->mid()),
      r(!child_index ? p->mid() : p->r) {}
    /// ノードの範囲の中央
    int mid() const { return (l + r) / 2; }
    /// 子ノードを取得する
    Node* child(bool child_index) {
      if(child_index == 0) {
        if(l_child == nullptr) l_child = new Node(e, this, 0);
        return l_child;
      } else {
        if(r_child == nullptr) r_child = new Node(e, this, 1);
        return r_child;
      }
    }
    /// 子ノードの情報からvalを更新する
    void update(auto &op) {
      T l_val = l_child == nullptr ? e : l_child->val;
      T r_val = r_child == nullptr ? e : r_child->val;
      val = op(l_val, r_val);
    }
  };
  Node* root;
public:
  /**
   * @brief 個数から空のSegmentTreeを生成する O(1)
   *
   * @param length 要素数
   * @param e 単位元
   * @param op 演算
   */
  inline explicit DynamicSegmentTree(int length, T e, function<T(T, T)> op)
      : e(e), op(op), n(bit_ceil(length)), root(new Node(e, e, 0, n)) {}
  /**
    * @brief i番目の要素を取得する O(log n)
    */
  inline Node* get_node(int i) const {
    Node *node = root;
    while(node->l + 1 < node->r) {
      node = node->child(node->mid() <= i);
    }
    return node;
  }
  /**
   * @brief i番目の要素を変更する O(log n) * op
   *
   * @param i インデックス (0-indexed)
   * @param a 更新後の要素
   */
  inline void set(int i, T a) {
    Node *node = get_node(i);
    node->val = a;
    while(node->p != nullptr) {
      node = node->p;
      node->update(op);
    }
  }
  /**
   * @brief i番目の要素を取得する O(log n)
   *
   * @param i インデックス (0-indexed)
   * @return i番目の要素
   */
  inline T get(int i) const { return get_node(i)->val; }
  /**
   * @brief [l, r)の範囲に対するクエリを行う O(log n) * op
   *
   * @param l クエリの左端 (0-indexed)
   * @param r クエリの右端 (0-indexed)
   * @return クエリの結果
   */
  inline T query(int l, int r) const {
    return _query(root, l, r);
  }
private:
  /**
    * @brief 特定のノードに対し、[l, r)の範囲に対するクエリを行う O(log n) * op
    *
    * @param node クエリを行うノード
    * @param l クエリの左端 (0-indexed)
    * @param r クエリの右端 (0-indexed)
    * @return クエリの結果
    */
  inline T _query(Node *node, int l, int r) const {
    if(r <= node->l || node->r <= l) return e;
    if(l <= node->l && node->r <= r) return node->val;
    return op(_query(node->child(0), l, r), _query(node->child(1), l, r));
  }
};
#line 5 "test/yukicoder/789__dynamic_seg.test.cpp"
signed main() {
  io_setup();
  int N;
  cin >> N;
  DynamicSegmentTree<int> seg(1'000'000'001, 0, [](int a, int b) { return a + b; });
  int ans = 0;
  rep(i, N) {
    int type;
    cin >> type;
    if(type == 0) {
      int x, y;
      cin >> x >> y;
      seg.set(x, seg.get(x) + y);
    } else {
      int l, r;
      cin >> l >> r;
      ans += seg.query(l, r + 1);
    }
  }
  cout << ans << endl;
}
            
            
            
        