士兵杀敌(二) 线段树
士兵杀敌(二)
时间限制: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
以1为开头的线段树要开两倍大小。#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<sstream> #include<algorithm> #include<queue> #include<deque> #include<iomanip> #include<vector> #include<cmath> #include<map> #include<stack> #include<set> #include<fstream> #include<memory> #include<list> #include<string> using namespace std; typedef long long LL; typedef unsigned long long ULL; #define MAXN 2000004 #define L 31 #define INF 1000000009 #define eps 0.00000001 /* 线段树的实现 */ struct Treenode { LL val; int l, r; }T[MAXN];//线段树 int a[MAXN],Max;//给出的数组 char op[10]; void build(int beg,int end,int root) { T[root].l = beg, T[root].r = end; if (beg == end) { T[root].val = a[beg]; } else { int mid = (beg + end) / 2; build(beg, mid, root * 2); build(mid+1, end, root * 2 + 1); T[root].val = T[root * 2].val + T[root * 2 + 1].val; } return; } /* LL query(int root, int nbeg, int nend, int qbeg, int qend)//这个好像没有办法处理 一种情况!? { if (qbeg > nend || qend < nbeg) return -1; if (qbeg <= nbeg&&qend >= nend) { cout << nbeg << ' ' << nend<<' '<<T[root].val<<endl; return T[root].val; } int mid = (nbeg + nend) / 2; return max(query(root * 2, nbeg, mid, qbeg, qend), query(root * 2 + 1, mid + 1, nend, qbeg, qend)); } */ int query(int i, int l, int r) { if (T[i].l == l&&T[i].r == r) return T[i].val; int mid = (T[i].l + T[i].r) / 2; if (r <= mid) return query(i * 2, l, r); else if (l > mid) return query(i * 2 + 1, l, r); else { return query(i * 2, l, mid) + query(i * 2 + 1, mid + 1, r); } } void add(int i, int num, int pos) { if (T[pos].l == i&&T[pos].r == i) { T[pos].val += num; return; } //cout << i << ' ' << num << ' ' << pos << ' ' << T[pos].l << ' ' << T[pos].r << endl; int mid = (T[pos].l + T[pos].r) / 2; if (i <= mid) add(i, num, pos*2); else add(i, num, pos*2+1); T[pos].val = T[pos * 2].val + T[pos * 2 + 1].val; } int main() { int n, q; scanf("%d%d", &n, &q); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); build(1, n, 1); int l, r; while (q--) { scanf("%s%d%d", op, &l, &r); if (op[0] == 'Q') printf("%d\n", query(1, l, r)); else add(l, r, 1); } return 0; }