线段树

 

 

参考资料:

  [1]:https://yq.aliyun.com/articles/252586

  [2]:挑战程序设计竞赛

目录:

  1. 相关概念以及性质
  2. 单点更新
  3. 区间更新
  4. 线段树+扫描线算法求矩阵面积
  5. 基于线段树的RMQ问题

自学笔记:

  1,2,3,4:

  pdf  提取码:ccu4 


 

  5.基于线段树的RMQ问题

    根据节点中维护的数据的不同,线段树可以提供不同的功能。

    例如:

    (1):RMQ问题

    (2):在log(n)时间内完成区间查询,区间修改问题

    (3):可以用来维护其他数据结构,比如树链剖分就可以用线段树维护轻重链

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ls(x) ((x)<<1)
 4 #define rs(x) ((x)<<1 | 1)
 5 const int maxn=1e5+50;
 6 
 7 int n;
 8 int a[maxn];
 9 struct Node
10 {
11     int l;
12     int r;
13     int val;//存储不同的数据可以对应不同的功能
14     int mid(){
15         return l+((r-l)>>1);
16     }
17 }segTree[4*maxn];//线段树所开辟的空间一般是原数据的四倍
18 
19 void pushUp(int pos)//想上更新
20 {
21     //每个节点的val值存储的是当前区间的最大值
22     segTree[pos].val=max(segTree[ls(pos)].val,segTree[rs(pos)].val);
23 }
24 void buildTree(int l,int r,int pos)//建树
25 {
26     segTree[pos].l=l,segTree[pos].r=r;
27     if(l == r)
28     {
29         segTree[pos].val=a[l];
30         return ;
31     }
32     int mid=l+((r-l)>>1);
33     buildTree(l,mid,ls(pos));
34     buildTree(mid+1,r,rs(pos));
35     pushUp(pos);
36 }
37 /**
38     区间查询分成三种可能的区间
39     1 都在左儿子这个区间
40     2 都在左儿子这个区间
41     3 都在左儿子这个区间
42 **/
43 int Query(int a,int b,int pos)
44 {
45     if(segTree[pos].l == a && segTree[pos].r == b)
46         return segTree[pos].val;
47     int mid=segTree[pos].mid();
48     if(b <= mid)//都在左儿子这个区间
49         return Query(a,b,ls(pos));
50     else if(a > mid)//都在左儿子这个区间
51         return Query(a,b,rs(pos));
52     else//都在左儿子这个区间
53         return max(Query(a,mid,ls(pos)),Query(mid+1,b,rs(pos)));
54 }
55 void Solve()
56 {
57     buildTree(1,n,1);
58     int a,b;
59     while(scanf("%d%d",&a,&b))//查询区间[a,b]的最大值
60         printf("%d\n",Query(a,b,1));
61 }
62 int main()
63 {
64     scanf("%d",&n);
65     for(int i=1;i <= n;++i)
66         scanf("%d",a+i);
67     Solve();
68     return 0;
69 }
70 
71 基于线段树的RMQ
基于线段树的RMQ问题

 

 

代码模板:

  

posted @ 2019-03-11 10:53  HHHyacinth  阅读(113)  评论(0编辑  收藏  举报