题目描述
NK 中学组织同学们去五云山寨参加社会实践活动,按惯例要乘坐火车去。由于 NK 中学的学生很多,在火车开之前必须清点好人数。
初始时,火车上没有学生。当同学们开始上火车时,年级主任从第一节车厢出发走到最后一节车厢,每节车厢随时都有可能有同学上下。年级主任走到第 m 节车厢时,他想知道前 m 节车厢上一共有多少学生,但是他没有调头往回走的习惯。也就是说每次当他提问时,m 总会比前一次大。
输入格式
第一行两个整数 n,k,表示火车共有 n 节车厢以及 k 个事件。
接下来有 k 行,按时间先后给出 k 个事件,每行开头都有一个字母 A
,B
或 C
。
- 如果字母为
A
,接下来是一个数 m,表示年级主任现在在第 m节车厢; - 如果字母为
B
,接下来是两个数 m,p,表示在第 m 节车厢有 p 名学生上车; - 如果字母为
C
,接下来是两个数 m,p,表示在第 m 节车厢有 p 名学生下车。
学生总人数不会超过 10^55。
输出格式
对于每个 A
,输出一行,一个整数,表示年级主任的问题的答案。
样例
样例输入
10 7A 1B 1 1B 3 1B 4 1A 2A 3A 10
样例输出
0123
数据范围与提示
对于 30%的数据,1≤n,k≤10^44,至少有 300030003000 个 A
;
对于 100% 的数据,1≤n≤5×10^5,1≤k≤10^5,,至少有 3×10^4个A
#include#include #include #include using namespace std;const long long maxn=500010;int n, k;inline void qread(int &x){ x = 0; int ch = getchar(); while(ch < '0' || ch > '9') ch =getchar(); while(ch >='0' && ch <= '9') x = 10 * x + ch - 48, ch = getchar();}struct BItree{ int data[maxn]; BItree(){ memset(data, 0, sizeof(data)); } void add(int x, int v){ for(; x <= n; x += (x&-x)) data[x] += v; } int sum(int x){ int ans = 0; for(; x; x -= (x&-x)) ans += data[x]; return ans; }}bi;int main(void){ qread(n); qread(k); while(k--){ string op; cin >> op; if(op == "A"){ int x; qread(x); printf("%d\n", bi.sum(x)); } else if(op == "B"){ int x, y; qread(x), qread(y); bi.add(x, y); } else{ int x, y; qread(x), qread(y); bi.add(x, -y); } }}
思路:
树状数组模板
个,1≤k≤105,至少有 3×1043\times 10^43×104 个 A
。