[线段树]模板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的主要内容,如果未能解决你的问题,请参考以下文章

P3834 模板可持久化线段树 1(主席树)

线段树模板总结

P3372 模板线段树 1

P3372 模板线段树 1

P3372 模板线段树 1

P3372 模板线段树 1(区间修改区间查询)(树状数组)