59
一道线段树单点更新的简单题目,但是因为一寒假没写了【原谅我的懒惰】,所以WA了好几次,还是要多多注意边界问题,错误全部处在树的边界上。
如果
要减少人数,就可以看作是添加上一个负数。
#include
#include
struct node
{
int left, right, num;
};
node tree[1000000];
int n, sum;
void Init()
{
int lim;
for (lim = 1; lim < n; lim <<= 1);
for (int i = lim; i < 2*lim; ++i)
{
tree[i].right = tree[i].left = i - lim + 1;
tree[i].num = 0;
}
for (int i = lim - 1; i > 0; --i)
{
tree[i].left = tree[2*i].left;
tree[i].right = tree[2*i + 1].right;
tree[i].num = 0;
}
}
void Insert(int id, int pos, int num)
{
if (pos <= tree[id].right && pos >= tree[id].left)
tree[id].num += num;
if (tree[id].left == tree[id].right)
return;
int mid = (tree[id].left + tree[id].right) >> 1;
if (mid < pos)
Insert(2*id + 1, pos, num);
else
Insert(2*id, pos, num);
}
void Query(int left, int right, int id)
{
if (left == tree[id].left && right == tree[id].right)
{
sum += tree[id].num;
return;
}
if (tree[id].left == tree[id].right)
return;
int mid = (tree[id].left + tree[id].right) >> 1;
if (left > mid)
Query(left, right, 2*id + 1);
else if (right <= mid)
Query(left, right, 2*id);
else
{
Query(left, mid, 2*id);
Query(mid + 1, right, 2*id + 1);
}
}
int main()
{
int T;
int cnt = 1;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
Init();
for (int i = 1; i <= n; ++i)
{
int x;
scanf("%d", &x);
Insert(1, i, x);
}
printf("Case %d:\n", cnt++);
char str[10];
while (scanf("%s", str) != EOF)
{
if (strcmp(str, "End") == 0)
break;
int x, y;
scanf("%d%d", &x, &y);
if (strcmp(str, "Add") == 0)
Insert(1, x, y);
else if (strcmp(str, "Sub") == 0)
{
int z = -y;
Insert(1, x, z);
}
else
{
sum = 0;
Query(x, y, 1);
printf("%d\n", sum);
}
}
}
return 0;
}