題意:敵兵陣地上有編號 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 50005int 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 );elseupdate ( 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 );elsereturn 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;}