E - 図書館の蔵書点検 / Library Inventory Check 解説 by admin
gpt-5.3-codexOverview
We treat each bookshelf’s contribution as \(A_i \times V_i\), and solve the problem of “answering range sum queries considering only bookshelves with \(D_i \le T\) as active.”
We sort queries offline by date \(T\) and use a Fenwick Tree (BIT) to efficiently compute range sums.
Analysis
The desired value for each query \((L, R, T)\) is:
\( \sum_{\substack{L \le i \le R \\ D_i \le T}} A_iV_i \)
1. Why the naive solution is too slow
If we iterate over the interval \([L,R]\) for each query and check \(D_i \le T\),
the worst case is \(O(NQ)\).
Given the constraints \(N+Q \le 2\times 10^5\), this won’t pass in time.
2. Key insight
If we process queries in increasing order of date \(T\),
the “set of available bookshelves” only monotonically increases (never decreases).
- Bookshelves with \(D_i \le T\) up to a certain point are active
- For the next larger \(T\), only additional bookshelves become active
By exploiting this “monotonic increase,” we don’t need to re-evaluate from scratch each time.
3. Managing range sums with BIT
We add the weight \(w_i=A_iV_i\) of each newly activated bookshelf \(i\) at position \(i\).
Then, the answer for a query at that point is simply the range sum:
\( \text{sum}(L,R) \)
which can be efficiently computed with a BIT.
Algorithm
- Store each bookshelf as \((D_i,\ i,\ w_i=A_iV_i)\) in an array.
- Store each query as \((T_j,\ L_j,\ R_j,\ id)\) in an array (\(id\) is the original index).
- Sort bookshelves in ascending order of \(D\), and queries in ascending order of \(T\).
- Place a pointer \(p\) at the beginning of the bookshelf array.
- Process queries in increasing order of \(T\):
while p < N and shelves[p].d <= T:- Add
wto the BIT at positionidx(activate it) p++
- Add
- Compute the range sum
sum(R)-sum(L-1)using BIT, and store it inans[id]
- Output
ansin the original query order.
Illustrative example
- When processing queries in date order, the BIT only contains “the sales of bookshelves whose repairs have been completed by that date.”
- Therefore, answering a query is simply “computing the range sum on the BIT at that point.”
Complexity
- Time complexity: \(O((N+Q)\log N)\)
(Sorting: \(O(N\log N + Q\log Q)\), each bookshelf addition and each query answer take \(\log N\) each) - Space complexity: \(O(N+Q)\)
Implementation notes
Use
long longsince \(A_iV_i\) and the sums can become large.Implementing BIT as 1-indexed is convenient (it matches the input shelf indices).
Since sorting disrupts the query order, carry an
idto output results in the original order.The key is using
while (D_i <= T)to “batch-add all bookshelves that become active at that point.”Source Code
#include <bits/stdc++.h>
using namespace std;
struct Fenwick {
int n;
vector<long long> bit;
Fenwick(int n = 0) { init(n); }
void init(int n_) {
n = n_;
bit.assign(n + 1, 0);
}
void add(int idx, long long val) {
for (; idx <= n; idx += idx & -idx) bit[idx] += val;
}
long long sumPrefix(int idx) const {
long long res = 0;
for (; idx > 0; idx -= idx & -idx) res += bit[idx];
return res;
}
long long sumRange(int l, int r) const {
if (l > r) return 0;
return sumPrefix(r) - sumPrefix(l - 1);
}
};
struct Shelf {
int d, idx;
long long w;
bool operator<(const Shelf& other) const {
return d < other.d;
}
};
struct Query {
int t, l, r, id;
bool operator<(const Query& other) const {
return t < other.t;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, Q;
cin >> N >> Q;
vector<Shelf> shelves;
shelves.reserve(N);
for (int i = 1; i <= N; ++i) {
long long A, V;
int D;
cin >> A >> D >> V;
shelves.push_back({D, i, A * V});
}
vector<Query> queries;
queries.reserve(Q);
for (int j = 0; j < Q; ++j) {
int L, R, T;
cin >> L >> R >> T;
queries.push_back({T, L, R, j});
}
sort(shelves.begin(), shelves.end());
sort(queries.begin(), queries.end());
Fenwick fw(N);
vector<long long> ans(Q);
int p = 0;
for (const auto& qu : queries) {
while (p < N && shelves[p].d <= qu.t) {
fw.add(shelves[p].idx, shelves[p].w);
++p;
}
ans[qu.id] = fw.sumRange(qu.l, qu.r);
}
for (int i = 0; i < Q; ++i) {
cout << ans[i] << '\n';
}
return 0;
}
This editorial was generated by gpt-5.3-codex.
投稿日時:
最終更新: