开学第一个周,总觉得还没进入状态,略有些疲惫和手忙脚乱,也因为课程时间安排的原因,周一到周三的课十分密集,导致自己进展也不大。
新学期第一半周,主要开始了对线段树的学习。我的理解:线段树是贯穿二分思想的完全二叉树,可以解决和树状数组类似的问题,像快速区间求和,对数组(主要是一维)进行操作维护,几乎所有树状数组的问题都可以解决。
假如说父区间是[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;
}
总的来说线段树要好理解的多,还需要抓紧看博客,抓紧开始做题了。
快速熟悉大二课程学习生活后,真心需要订一份计划安排,对学习时间与科目安排一下。