結果
問題 |
No.789 範囲の合計
|
ユーザー |
![]() |
提出日時 | 2025-03-10 03:04:44 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 182 ms / 1,000 ms |
コード長 | 3,779 bytes |
コンパイル時間 | 1,178 ms |
コンパイル使用メモリ | 96,024 KB |
実行使用メモリ | 20,584 KB |
最終ジャッジ日時 | 2025-03-10 03:04:48 |
合計ジャッジ時間 | 3,781 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 15 |
ソースコード
#include <iostream> #include <vector> #include <set> #include <unordered_map> #include <algorithm> using namespace std; // 圧縮クラス(必要なら利用できますが、以下のコードでは直接マッピングを作成しています) class Compression { public: int n; unordered_map<int, int> v2i; Compression(const set<int>& s) { n = s.size(); vector<int> sorted(s.begin(), s.end()); // ソートは set で既に済んでいる場合もありますが明示的に実施 sort(sorted.begin(), sorted.end()); for (int i = 0; i < sorted.size(); i++) { v2i[sorted[i]] = i; } } int size() const { return n; } // val のインデックスを返す int index(int val) { return v2i[val]; } }; // Fenwick Tree (Binary Indexed Tree) クラス class FenwickTree { public: vector<long long> data; int n; // 内部データのサイズ(n+10 で確保) // コンストラクタ:引数 n はサイズの目安(さらに余裕を持たせる) FenwickTree(int n) { this->n = n + 10; data.assign(this->n, 0LL); } // 点 p (0-indexed) に x を加算 void add(int p, int x) { // 0 <= p < n が前提 p++; // 1-indexed に変換 while (p < data.size()) { data[p] += x; p += p & -p; } } // 区間 [0, p] の和 (p は 0-indexed) long long sum(int p) { // 0 <= p < n p++; // 1-indexed に変換 long long s = 0; while (p > 0) { s += data[p]; p -= p & -p; } return s; } // 区間 [l, r] の和 (l, r は 0-indexed) long long rangesum(int l, int r) { long long s = sum(r); if (l > 0) s -= sum(l - 1); return s; } }; struct Query { int type; // 0: update, 1: range query int a, b; // update の場合: a = x, b = y; range query の場合: a = l, b = r }; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N; cin >> N; vector<Query> queries; set<int> inds; // 圧縮用の値を保持 for (int i = 0; i < N; i++){ int type; cin >> type; if (type == 0) { // a[x] += y int x, y; cin >> x >> y; x--; // 0-indexed に変換 queries.push_back({0, x, y}); inds.insert(x); } else if (type == 1) { // 区間 [l, r] の和 int l, r; cin >> l >> r; l--; r--; // 0-indexed に変換 queries.push_back({1, l, r}); inds.insert(l); inds.insert(r); } } // インデックス圧縮: 重複のない値をソートして、それぞれに 0-indexed の番号を割り当てる vector<int> sorted_inds(inds.begin(), inds.end()); sort(sorted_inds.begin(), sorted_inds.end()); unordered_map<int, int> v2i; for (int i = 0; i < sorted_inds.size(); i++){ v2i[sorted_inds[i]] = i; } // FenwickTree の初期化(サイズは v2i のサイズ + 10) FenwickTree ft(sorted_inds.size() + 10); long long ans = 0; // クエリの処理 for (int i = 0; i < N; i++){ if (queries[i].type == 0) { int x = queries[i].a; int y = queries[i].b; int p = v2i[x]; ft.add(p, y); } else if (queries[i].type == 1) { int l = queries[i].a; int r = queries[i].b; int li = v2i[l]; int ri = v2i[r]; long long res = ft.rangesum(li, ri); ans += res; } } cout << ans << "\n"; return 0; }