敌兵布阵Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 127509 Accepted Submission(s): 53425 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况。由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视。
Input 第一行一个整数T,表示有T组数据。
Output 对第i组数据,首先输出“Case i:”和回车,
Sample Input 1 10 1 2 3 4 5 6 7 8 9 10 Query 1 3 Add 3 6 Query 2 7 Sub 10 2 Add 6 3 Query 3 10 End
Sample Output Case 1: 6 33 59
|
这道题是一道线段树的基础应用,包括区间查询和点修改,也适用于树状数组入门,线段树刚学,比较懵逼,做完这道题后,感觉还好。这道题需要注意的是要用c不能用c++的cin,cout会超时,改成printf和scanf就过了。
# include <iostream>
# include <cstring>
# include <string>
# include <cstdio>
using namespace std;
const int maxn = 55555;
int Arr[maxn], n, Sum[maxn << 2];//开4倍空间;
//求区间和
void Pushup(int rt)
{
Sum[rt] = Sum[rt << 1] + Sum[rt << 1 | 1];//当前这一区间和等于我的子区间和
return ;
}
void Build(int l, int r, int rt)//左右区间和实际存储位置
{
if(l == r)
{
Sum[rt] = Arr[l];//若到达就存储Arr数组的值
return ;
}
int mid = (l + r) >> 1;
//左递归
Build(l, mid, rt << 1);
//右递归
Build(mid + 1, r, rt << 1|1);
Pushup(rt);//更新信息,建立了一个线段树
return ;
}
//点修改
void Updata(int L, int add, int l, int r, int rt)//[L,R]表示实际操作区间,lr,表示当前区间,rt当前结点编号
{
if(l == r)
{
Sum[rt] += add;
return ;
}
int mid = (l + r) >> 1;
if(L <= mid)
{
Updata(L, add, l, mid, rt << 1);
}
else
{
Updata(L, add, mid + 1, r, rt << 1 | 1);
}
Pushup(rt);
}
//查询线段树
int Query(int L, int R, int l, int r, int rt)//[L,R]表示操作区间,[l,r]表示当前区间,rt:当前节点编号
{
if(l >= L && r <= R)
{
return Sum[rt];//在区间内直接返回
}
int mid = (l + r) >> 1;
int ans = 0;
if(L <= mid)
{
ans += Query(L, R, l, mid, rt << 1);
}
if(R > mid)
{
ans += Query(L, R, mid + 1, r, rt << 1 | 1);
}
return ans;
}
int main(int argc, char *argv[])
{
int t;
while(scanf("%d", &t) != EOF)
{
for(int k = 1; k <= t; ++k)
{
// cout << "Case "<< k <<":" << endl;
// cin >> n;
scanf("%d", &n);
memset(Arr, false, sizeof(Arr));
memset(Sum, false, sizeof(Sum));
for(int i = 1; i <= n; ++i)
{
// cin >> Arr[i];
scanf("%d", &Arr[i]);
}
Build(1, n, 1);
char str[10];
printf("Case %d:\n", k);
while(scanf("%s", str))
{
if(str[0] == 'A')
{
int x, y;
scanf("%d%d",&x, &y);
Updata(x, y, 1, n, 1);
}
else if(str[0] == 'S')
{
int x, y;
scanf("%d%d",&x, &y);
Updata(x, -y, 1, n, 1);
}
else if(str[0] == 'Q')
{
int x, y;
scanf("%d%d",&x, &y);
int ans = Query(x, y, 1, n, 1);
printf("%d\n", ans);
}
else
{
break;
}
}
}
}
return 0;
}