题意:敌兵阵地上有编号 1 - n 的营地, 每个营地的人员会增加或者减少。题中有四种操作。
(1) Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30)(2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30);(3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数;(4)End 表示结束,这条命令在每组数据最后出现;
题解:
#include <cstring>
#include <iostream>
using namespace std;
#define L(u) ( u << 1 )
#define R(u) ( u << 1 | 1 )
#define N 50005
int sum[N];
struct item { int l, r, v; } node[N*4];
void build ( int u, int l, int r )
{
node[u].l = l;
node[u].r = r;
node[u].v = sum[r] - sum[l-1];
if ( l == r ) return;
int mid = ( l + r ) >> 1;
build ( L(u), l, mid );
build ( R(u), mid + 1, r );
}
void update ( int u, int pos, int val )
{
if ( node[u].l == pos && node[u].r == pos )
{
node[u].v += val;
return;
}
int mid = ( node[u].l + node[u].r ) >> 1;
if ( pos <= mid )
update ( L(u), pos, val );
else
update ( R(u), pos, val );
node[u].v = node[L(u)].v + node[R(u)].v;
}
int query ( int u, int l, int r )
{
if ( l <= node[u].l && node[u].r <= r )
return node[u].v;
int mid = ( node[u].l + node[u].r ) >> 1;
if ( r <= mid )
return query ( L(u), l, r );
else if ( l > mid )
return query ( R(u), l, r );
else
return query ( L(u), l, mid ) + query ( R(u), mid+1, r );
}
int main()
{
char oper[10];
int t, n, i, a, b, num, k = 1;
scanf("%d",&t);
while ( t-- )
{
sum[0] = 0;
scanf("%d",&n);
for ( i = 1; i <= n; i++ )
{
scanf("%d",&num);
sum[i] = sum[i-1] + num;
}
build ( 1, 1, n );
printf("Case %d:\n",k++);
while ( scanf("%s",oper) )
{
if ( !strcmp(oper,"End") ) break;
if ( !strcmp(oper,"Query") )
{
scanf("%d%d",&a,&b);
printf("%d\n",query ( 1, a, b ));
}
else if ( !strcmp(oper,"Sub") )
{
scanf("%d%d",&a,&b);
update ( 1, a, -b );
}
else
{
scanf("%d%d",&a,&b);
update ( 1, a, b );
}
}
}
return 0;
}