結果
| 問題 | No.789 範囲の合計 |
| コンテスト | |
| ユーザー |
norioc
|
| 提出日時 | 2025-03-10 03:04:44 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.89.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;
}
norioc