1 条题解
-
0
思路与算法
把每节车厢的人数作为一个数组,初始全0。B m p 对第 m 项加 p,C m p 对第 m 项减 p,A m 查询前 m 项之和。树状数组支持点增减和前缀和,直接依次处理事件即可。
正确性说明
每个上下车事件只改变指定车厢的人数,点更新会把这次变化加入所有包含该位置的树状数组区间。查询前缀时,这些区间恰好不重不漏地覆盖1到m,因此得到主任询问时前m节车厢的实时人数。按时间顺序执行所有事件,答案始终对应当前状态。
复杂度
时间 O(N+K log N),空间 O(N)。
易错点
已经走过的车厢仍会有人上下车,这些变化也要影响后续答案。下车是负更新,不能删除整个车厢。题目保证询问位置严格增加,但树状数组不依赖这个条件也能正确维护。
参考代码(C++11)
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k; cin >> n >> k; vector<int> bit(n + 1); while (k--) { char op; int m, p; cin >> op >> m; if (op == 'A') { int ans = 0; for (int i = m; i; i -= i & -i) ans += bit[i]; cout << ans << '\n'; } else { cin >> p; if (op == 'C') p = -p; for (int i = m; i <= n; i += i & -i) bit[i] += p; } } }
- 1