ACM周中训练笔记—8月31日

来源:互联网 发布:阿里云域名注册查询 编辑:程序博客网 时间:2024/06/07 06:30

         开学第一个周,总觉得还没进入状态,略有些疲惫和手忙脚乱,也因为课程时间安排的原因,周一到周三的课十分密集,导致自己进展也不大。

        新学期第一半周,主要开始了对线段树的学习。我的理解:线段树是贯穿二分思想的完全二叉树,可以解决和树状数组类似的问题,像快速区间求和,对数组(主要是一维)进行操作维护,几乎所有树状数组的问题都可以解决。

       假如说父区间是[a,b],其左子区间为[a,(a+b)/2],右子区间为[((a+b)/2)+1,b],将所给数组以完全二叉树结构的存储,由此[i,i]就是存储了第i个数的值,逐层向上就可以存该区间下满足条件的值。

      void build(int l,int r,int rt)//建树,rt表示二叉树的结点序号,sum[]是二叉树组存储
      {
           if(l==r)
           {
               cin>>sum[rt];
               return ;
           }
           int mid=(l+r)/2;//分割两半各自递归建树
           build(l,mid,rt*2);
           build(mid+1,r,rt*2+1);
           sum[rt]=sum[rt*2]+sum[rt*2+1];
      }

      void update(int p,int add,int l,int r,int rt)//把第p个数加上add值,rt表示二叉树的结点序号
      {
          if(l==r)
          {
             sum[rt]=sum[rt]+add;
             return ;
          }
          int m=(l+r)/2;
          if(p<=m) update(p,add,l,m,rt*2);
          else update(p,add,m+1,r,rt*2+1);
          sum[rt]=sum[rt*2]+sum[rt*2+1];
      }

     int query(int L,int R,int l,int r,int rt)//对[L,R]区间的元素和
     {
         if(l==r)
         {
            return sum[rt];
         }
        int m=(l+r)/2;
        int res=0;
        if(m>=L)    res=res+query(L,R,l,m,rt*2);
        if(m<R)     res=res+query(L,R,m+1,r,rt*2+1);
        return res;
     }

     总的来说线段树要好理解的多,还需要抓紧看博客,抓紧开始做题了。

      快速熟悉大二课程学习生活后,真心需要订一份计划安排,对学习时间与科目安排一下。

原创粉丝点击