士兵杀敌(二)
时间限制:1000 ms | 内存限制:65535 KB
难度:5
-
描述
-
南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的。
小工是南将军手下的军师,南将军经常想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧。
南将军的某次询问之后士兵i可能又杀敌q人,之后南将军再询问的时候,需要考虑到新增的杀敌数。
-
输入
- 只有一组测试数据
第一行是两个整数N,M,其中N表示士兵的个数(1<N<1000000),M表示指令的条数。(1<M<100000)
随后的一行是N个整数,ai表示第i号士兵杀敌数目。(0<=ai<=100)
随后的M行每行是一条指令,这条指令包含了一个字符串和两个整数,首先是一个字符串,如果是字符串QUERY则表示南将军进行了查询操作,后面的两个整数m,n,表示查询的起始与终止士兵编号;如果是字符串ADD则后面跟的两个整数I,A(1<=I<=N,1<=A<=100),表示第I个士兵新增杀敌数为A.
输出 - 对于每次查询,输出一个整数R表示第m号士兵到第n号士兵的总杀敌数,每组输出占一行 样例输入
-
5 6 1 2 3 4 5 QUERY 1 3 ADD 1 2 QUERY 1 3 ADD 2 3 QUERY 1 2 QUERY 1 5
样例输出 -
6 8 8 20
- 只有一组测试数据
解题思路:
这题我是用线段树做的,主要用到了线段树的,建树,更新和查询的操作,在输入每个士兵开始的杀敌数和ADD指令时,进行更新操作,在进行qyery时,进行查询操作,线段树主要维护某个区间内的士兵的杀敌总数,详见代码:
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
#include<bits/stdc++.h>
#define maxn 1000000 using namespace std; int b1[maxn], sum; struct Node { int left;///左边界 int right;///右边界 int num;///杀敌人数 } node[maxn * 4]; void buid(int i, int left, int right) { ///建树 node[i].left = left; node[i].right = right; node[i].num = 0; ///杀敌人数,初始化为零 if(left == right) { b1[left] = i; ///存储第left号士兵,在线段树内的节点编号 return ; } int mid = (left + right) / 2; buid(i << 1, left, mid); buid(i << 1 | 1, mid + 1, right); } void update(int i, int add) { ///更新操作 if(i == 1) { node[i].num += add; return ; } node[i].num += add; update(i >> 1, add); } void query(int i, int l, int r) { ///查询操作 if(node[i].left == l && node[i].right == r) { sum += node[i].num; return ; } i = i << 1; if(l <= node[i].right) { if(r <= node[i].right) query(i, l, r); else query(i, l, node[i].right); } i++; if(r >= node[i].left) { if(l >= node[i].left) query(i, l, r); else query(i, node[i].left, r); } } int main() { int n, m, a, b, c; char s[10]; scanf("%d %d", &n, &m); buid(1, 1, n); for(int i = 1; i <= n; i++) { scanf("%d", &c); update(b1[i], c); } while(m--) { scanf("%s %d %d", s, &a, &b); if(strcmp(s, "QUERY") == 0) { sum = 0; query(1, a, b); printf("%d\n", sum); } else update(b1[a], b); } return 0; } |