2018年6月1号(线段树(1))

  今天是六一儿童节,先祝各位六一儿童节快乐

  今天想和大家一起学习一下线段树:
  
1. 创建线段树

  对于线段树我们可以选择和普通二叉树一样的链式结构。我们可以用数组来存储,下面的讨论及代码都是数组来存储线段树,节点结构如下(注意到用数组存储时,有效空间为2n-1,实

  际空间确不止这么多,比如上面的线段树中叶子节点1、3虽然没有左右子树,但是的确占用了数组空间,实际空间是满二叉树的节点数目。 是树的高度,但是这个空间复杂度也是

  O(n) 的 )。

  定义包含n个节点的线段树 SegTreeNode segTree[n],segTree[0]表示根节点。那么对于节点segTree[i],它的左孩子是segTree[2*i+1],右孩子是segTree[2*i+2]。

  我们可以从根节点开始,平分区间,递归的创建线段树,线段树的创建函数如下:

  

1 int add(int x,int l,int r)
2 {
3     s[x].l=l;s[x].r=r;
4     int mid=(l+r)/2;//利用二分的思想来做;
5     if(l==r)
6     return s[x].dis=a[l];
7     s[x].dis=add(x*2,l,mid)+add(x*2+1,mid+1,r);//这只是求和;
8     return s[x].dis;
9 }

   2.修改

  我么就以一个最常见的例子来说

  最经常的是“C,x,y”,把a[x]改成v;

  代码:

  

 1 void chag(int p,int x,int v)
 2 {
 3     if(t[p].l==t[p].r)
 4     {
 5         t[p].dat+=v;
 6         return;
 7     }
 8     int mid=(t[p].l+t[p].r)/2;
 9     if(mid>=x)
10     chag(p*2,x,v);
11     else
12     chag(p*2+1,x,v);
13     t[p].dat=t[2*p].dat+t[2*p+1].dat;
14 }

  最后求了,我给出一个求和代码

  代码:

  

 1 int asked(int p,int l,int r)
 2 {
 3     if(l<=t[p].l&&r>=t[p].r)
 4         return t[p].dat;
 5     int mid=(t[p].l+t[p].r)/2;
 6     int maxx=0;
 7     if(l<=mid)
 8         maxx+=asked(p*2,l,r);
 9     if(r>mid)
10         maxx+=asked(p*2+1,l,r);
11     return maxx;
12 }

today is over

Keep on going never give up.   勇往直前, 决不放弃!
原文地址:https://www.cnblogs.com/zssmg/p/9123473.html