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

xiaoxiao2021-02-28  100

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

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

       假如说父区间是[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;      }

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

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

转载请注明原文地址: https://www.6miu.com/read-55169.html

最新回复(0)