ACM-9月3日周日周末训练心得

来源:互联网 发布:手机直播点歌软件 编辑:程序博客网 时间:2024/05/16 14:21

     今天老师发了新的专题,是线段树的,今天就用空余的时间看了看前辈的博客,了解了一下线段树的内容,发现树状数组能解决的问题线段树基本都能解决,线段树的用法与树状数组的用法似乎有些相似,但是线段树能维护一段区间的值,不像树状数组,改变一个地方的值就会整体更新,线段树有时候就比树状数组好用了

//线段树需要维护的信息  int sum[maxn*4];  #define lson i*2, l, m  #define rson i*2+1, m+1, r  //i节点收集子节点的统计结果  void PushUp(int i)  {      sum[i]=sum[i*2]+sum[i*2+1];  }  //递归建立线段树  void build(int i,int l,int r)  {      if(l==r)      {          scanf("%d",&sum[i]);          return ;      }        int m=(l+r)/2;      build(lson);      build(rson);      PushUp(i);//收集子节点的结果  }  //在当前区间[l, r]内查询区间[ql, qr]间的目标值  //且能执行这个函数的前提是:[l,r]与[ql,qr]的交集非空  //其实本函数返回的结果也是 它们交集的目标值  int query(int ql,int qr,int i,int l,int r)  {      //目的区间包含当前区间      if(ql<=l && r<=qr) return sum[i];        int m=(l+r)/2;      int res=0;      if(ql<=m) res += query(ql,qr,lson);      if(m<qr) res += query(ql,qr,rson);      return res;  }  //update这个函数就有点定制的意味了  //本题是单点更新,所以是在区间[l,r]内使得第id数的值+val  //如果是区间更新,可以update的参数需要将id变为ql和qr  void update(int id,int val,int i,int l,int r)  {      if(l==r)      {          sum[i] += val;          return ;      }      int m=(l+r)/2;      if(id<=m) update(id,val,lson);      else update(id,val,rson);      PushUp(i);//时刻记住维护i节点统计信息正确性  }
    主要也是四个函数,收集子节点的情况统计sum,建立线段树,查找某一处的值,更新维护区间或点。

    今天就看了这个4个函数,再抽时间看下面的把。

    新的一周也要加油。


原创粉丝点击