[线段树]模板1
Posted GldHkkowo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[线段树]模板1相关的知识,希望对你有一定的参考价值。
【模板】线段树1
题目描述
给定一个无序数列,有四种操作:
1.令数列中的某个数加上某个数
2.求一个区间的和
3.查询一段区间内的最大值;
4.查询一段区间内的最小值;
输入
输入的第1行,共有两个数n和q,表示数列长度和操作次数
输入的第2行,共有n个数,表示该数列
接下来共有q行,每行有三个数
第1个数为操作类型,具体如下
若是第1种操作,接下来两个数x,y分别表示将第x个数加y
若是第2~4种操作,接下来两个数x,y表示闭区间的左右端点
输出
输出共有若干行,对于每一个询问输出一个整数结果
样例输入
5 4
1 2 3 4 5
2 1 4
1 3 -2
3 1 5
4 2 3
样例输出
10
5
1
提示
1<=n,q<=200000
保证所有数据在c/c++语言的INT范围内,pascal语言的longint范围内。
代码:
1 #include <cstdio> 2 #define MAXN 200005 3 #define TREE_SIZE 530000 4 5 struct node { 6 int sum, min, max; 7 } t[TREE_SIZE]; 8 9 int n, m, a[MAXN]; 10 inline int min(int a, int b) { 11 return a < b ? a : b; 12 } 13 inline int max(int a, int b) { 14 return a > b ? a : b; 15 } 16 inline node join(node a, node b) { 17 node c; 18 c.sum = a.sum +b.sum; 19 c.max = max(a.max, b.max); 20 c.min = min(a.min, b.min); 21 return c; 22 } 23 void build(int l, int r, int k) { 24 if (l == r) { 25 t[k].sum =t [k].min = t[k].max = a[l]; 26 return; 27 } 28 int mid = l + r >> 1; 29 build(l, mid, k << 1); 30 build(mid + 1, r, k << 1 | 1); 31 t[k] = join(t[k << 1], t[k << 1 | 1]); 32 } 33 node query(int l, int r, int a, int b, int k) { 34 if(l >= a && r <= b) { 35 return t[k]; 36 } 37 int mid = l + r >> 1; 38 if (b <= mid) { 39 return query(l, mid, a, b, k << 1); 40 } 41 if (a > mid) { 42 return query(mid + 1, r, a, b, k << 1 | 1); 43 } 44 return join(query(l, mid, a, b, k << 1), query(mid + 1, r, a, b, k << 1 | 1)); 45 } 46 void modify_s(int l, int r, int a, int b, int k) { 47 if (l == a && r == a) { 48 t[k].sum += b; 49 t[k].max = t[k].min = t[k].sum; 50 return; 51 } 52 int mid = l + r >> 1; 53 if (a <= mid) { 54 modify_s(l, mid, a, b, k << 1); 55 } 56 else { 57 modify_s(mid + 1, r, a, b, k << 1 | 1); 58 } 59 t[k] = join(t[k << 1], t[k << 1 | 1]); 60 } 61 int main() { 62 int o, b, c; 63 scanf("%d%d", &n, &m); 64 for(int i = 1; i <= n; ++i) { 65 scanf("%d",a + i); 66 } 67 build(1, n, 1); 68 while (m--) { 69 scanf("%d %d %d", &o, &b, &c); 70 if (o == 1) { 71 modify_s(1, n, b, c, 1); 72 } 73 if (o == 2) { 74 printf("%d\n", query(1, n, b, c, 1).sum); 75 } 76 if (o == 3) { 77 printf("%d\n", query(1, n, b, c, 1).max); 78 } 79 if (o == 4) { 80 printf("%d\n",query(1, n, b, c, 1).min); 81 } 82 } 83 return 0; 84 }
以上是关于[线段树]模板1的主要内容,如果未能解决你的问题,请参考以下文章