童鞋说用树状数组做, 知识点是 区间改,单点查。
#include <stdio.h>
#include <string.h>
#define MAX 20001
struct AttackBound {
int left, right;
};
int attackNum[MAX];
int lowbit(int x) {
return x & (-x);
}
void update(int x, int delta) {
while (x <= MAX) {
attackNum[x] += delta;
x += lowbit(x);
}
}
int getSum(int x) {
int sum = 0;
while (x > 0) {
sum += attackNum[x];
x -= lowbit(x);
}
return sum;
}
int main() {
int caseNum, c;
int n, q, t;
char query[15];
int time, protectNum[MAX], cdTime[MAX];
AttackBound attack[MAX];
int pos;
int i, j;
while (scanf("%d", &caseNum) == 1) {
c = 0;
while (caseNum--) {
c++;
time = 0;
memset(protectNum, 0, sizeof(protectNum));
memset(cdTime, 0, sizeof(cdTime));
memset(attackNum, 0, sizeof(attackNum));
memset(attack, 0, sizeof(attack));
printf("Case %d:\n", c);
scanf("%d%d%d", &n, &q, &t);
for (i = 0; i < q; i++) {
scanf("%s", query);
if (query[0] == 'A') {
time++;
scanf("%d%d", &attack[time].left, &attack[time].right);
// 更新一段区间,不影响其他区间的修改
update(attack[time].left, 1);
update(attack[time].right + 1, -1);
} else {
scanf("%d", &pos); // 查询位置
for (j = cdTime[pos]; j <= time; j++) {
if (attack[j].left <= pos && pos <= attack[j].right) {
protectNum[pos]++;
cdTime[pos] = j + t;
j = j + t - 1;
}
}
printf("%d\n", getSum(pos) - protectNum[pos]);
}
}
}
}
return 0;
}