码迷,mamicode.com
首页 > 其他好文 > 详细

线段树--数据结构专题学习

时间:2016-04-23 01:29:07      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

这两周是数据结构专题的学习,,被专题的题目虐得死去活来==

 

线段树:简单的说就是把【1,n】的区间二分,【1,(1+n)/2】左子树,【(1+n)/2+1,n】右子树

    就这样一直分下去,直到都是【x,x】这样的区间。这样就构成了一颗树了^-^

          有这样一棵树,我们就可以在节点中储存区间的和啊,区间内的最大值啊,最小值等等。。这就是线段树的附加信息了,也是题目中的重点。。

    我们可以用一个数组(长度为k)储存原区间的初始值,然后根据这个建树,所以这个树的节点数最多为4*K;

    对于每个节点i,其左子树为i*2,右子树为i*2+1,父母节点为i/2。该区间的sum为左右子树区间和的和,最大最小值同理。。。

    线段树的建立,修改,查询都是用递归写的。

    所以在对单个数值时,必定会影响到其祖先节点,所以从上往下写。递归后修改节点信息。

    线段树的查询也是如此,从上向下查询。

    至于区间修改,,,我还在看。。。

    对了,修改和查询的复杂度都是lgn

    先贴模板

技术分享
 1 struct node
 2 {
 3     int maxt,sum;
 4     int left,right;
 5 };
 6 struct node tree[4*K];
 7 int a[k];
 8 void build(int id,int l,int r)
 9 {
10     tree[id].left=l;tree[id].right=r;
11     if(l==r)
12     {
13         tree[id].maxt=tree[id].sum=a[l];
14     }
15     else
16     {
17         build(2*id,l,(l+r)/2);
18         build(2*id+1,(l+r)/2+1,r);
19         tree[id].maxt=max(tree[2*id].maxt,tree[2*id+1].maxt);
20         tree[id].sum=tree[2*id].sum+tree[2*id+1].sum;
21     }
22 }
23 int queryMax(int id,int l,int r)
24 {
25     if(l==tree[id].left && r==tree[id].right)
26         return tree[id].maxt;
27     int mid=(tree[id].left+tree[id].right)>>1;
28     int ret=0;
29     if(r<=mid)
30         ret=max(ret,queryMax(id<<1,l,r));
31     else if(l>=mid+1)
32         ret=max(ret,queryMax((id<<1)+1,l,r));
33     else
34     {
35         int a,b;
36         a=queryMax(id<<1,l,mid);
37         b=queryMax((id<<1)+1,mid+1,r);
38         return max(a,b);
39     }
40     return ret;
41 }
42 int update(int id,int pos,int v)
43 {
44     if(tree[id].left == tree[id].right)
45     {
46         tree[id].sum=tree[id].maxt=val;
47     }
48     else
49     {
50         int mid=(tree[id].left+tree[id].right)>>1;
51         if (pos<=mid) update(id*2,pos,v);
52             else update(id*2+1,pos,v);
53         tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
54         tree[id].maxt=max(tree[id*2].maxt,tree[id*2+1].maxt);
55     }
56     return 0;
57 }
58 
59 int query(int id,int l,int r)
60 {
61         if (tree[id].left==l&&tree[id].right==r)
62             return tree[id].sum; 
63         else
64         {
65             int mid=(tree[id].left+tree[id].right)>>1;    
66             if (r<=mid) return query(id*2,l,r);
67             else if (l>mid) return query(id*2+1,l,r)
68             else return query(id*2,l,mid)+query(id*2+1,mid+1,r);
69         }
70     }
View Code

 

线段树--数据结构专题学习

标签:

原文地址:http://www.cnblogs.com/weeping/p/5423382.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!