• 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.   勇往直前, 决不放弃!
  • 相关阅读:
    c# XML和实体类之间相互转换(序列化和反序列化)
    反序列化-通过创建Class对象及属性
    .net C#中页面之间传值传参的六种方法
    C#对XML、JSON等格式的解析
    c#大圣之路笔记——c# DataGrid checkbox 操作
    python(十五)
    python(十四)
    python(十三)
    python(十二)
    python(十一)
  • 原文地址:https://www.cnblogs.com/zssmg/p/9123473.html
Copyright © 2020-2023  润新知