清点人数 LibreOJ - 10116

题目描述

NK 中学组织同学们去五云山寨参加社会实践活动,按惯例要乘坐火车去。由于 NK 中学的学生很多,在火车开之前必须清点好人数。

初始时,火车上没有学生。当同学们开始上火车时,年级主任从第一节车厢出发走到最后一节车厢,每节车厢随时都有可能有同学上下。年级主任走到第 mm 节车厢时,他想知道前 mm 节车厢上一共有多少学生,但是他没有调头往回走的习惯。也就是说每次当他提问时,mm 总会比前一次大。

输入格式

第一行两个整数 n,kn,k,表示火车共有 nn 节车厢以及 kk 个事件。

接下来有 kk 行,按时间先后给出 kk 个事件,每行开头都有一个字母 AB 或 C

  • 如果字母为 A,接下来是一个数 mm,表示年级主任现在在第 mm 节车厢;
  • 如果字母为 B,接下来是两个数 m,pm,p,表示在第 mm 节车厢有 pp 名学生上车;
  • 如果字母为 C,接下来是两个数 m,pm,p,表示在第 mm 节车厢有 pp 名学生下车。

学生总人数不会超过 105105。

输出格式

对于每个 A ,输出一行,一个整数,表示年级主任的问题的答案。

样例

InputOutput
10 7
A 1
B 1 1
B 3 1
B 4 1
A 2
A 3
A 10
0
1
2
3

数据范围与提示

对于 30%30% 的数据,1n,k1041≤n,k≤104,至少有 30003000 个 A

对于 100%100% 的数据,1n5×105,1k1051≤n≤5×105,1≤k≤105,至少有 3×1043×104 个 A

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
ll Case, n, m, i, j, k;
ll a[1500010];
inline void add(ll x, ll y) {
    for (ll i = x; i <= n; i += i & (-i)) {
        a[i] += y;
    }
}
inline ll getsum(ll x) {
    ll sum = 0;
    for (ll i = x; i; i -= i & (-i)) {
        sum += a[i];
    }
    return sum;
}
int main() {
    scanf("%lld%lld", &n, &k);
    for (i = 1; i <= k; i++) {
        char A;
        cin >> A;
        ll p;
        if (A == 'A') {
            cin >> m;
            cout << getsum(m) << endl;
        }
        else if (A == 'B') {
            cin >> m >> p;
            add(m, p);
        }
        else{
            cin >> m >> p;
            add(m, -p);
        }
    }
}

 

posted @ 2021-01-04 20:42  XXXSANS  阅读(139)  评论(0编辑  收藏  举报