题目大意:有一个长为n的长城,进行q次操作,d为防护罩的冷却时间,Attack表示区间a-b的墙将在1秒后受到攻击,
询问表示计算第a块墙受到攻击的次数,被防护罩抵消的不算。
解题思路:树状数组,更新区间查询点,每次攻击区间a-b时,只要进行add(a,1); add(b+1, -1);然后第i堵墙受到的总攻击次数即为sum(i)。实际受到攻击的次数=总攻击次数-防护次数。防护次数的计算是将每次攻击的区间记录下来,然后枚举被抵挡的次数。
#include <stdio.h>
#include <string.h>
const int N = 20005;
int n, q, d, ti, v[N], l[N], r[N], cnt[N], rec[N];
void init() {
scanf("%d%d%d", &n, &q, &d);
ti = 0;
memset(cnt, 0, sizeof(cnt));
memset(rec, 0, sizeof(rec));
memset(v, 0, sizeof(v));
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
}
void add(int x, int val) {
while (x <= n) {
v[x] += val;
x += (x & (-x));
}
}
int sum(int x) {
int ans = 0;
while (x > 0) {
ans += v[x];
x -= (x &(-x));
}
return ans;
}
void solve() {
int a, b;
char o[10];
for (int i = 0; i < q; i++) {
scanf("%s", o);
if (o[0] == 'A') {
scanf("%d%d", &a, &b);
add(a, 1); add(b+1, -1);
l[ti] = a, r[ti] = b;
ti++;
} else {
scanf("%d", &a);
for (int j = rec[a]; j < ti; j++) if (l[j] <= a && r[j] >= a) {
rec[a] = j + d;
cnt[a]++;
j += d - 1;
}
printf("%d\n", sum(a) - cnt[a]);
}
}
}
int main() {
int cas;
scanf("%d", &cas);
for (int i = 1; i <= cas; i++) {
printf("Case %d:\n", i);
init();
solve();
}
return 0;
}