学习笔记--树链剖分

前言

树链剖分是一个很好用的处理树上统计信息的方法,大致思想就是把树上路径分成\(log N\)条链,再用线段树之类的数据结构维护一下,所以时间复杂度得到了保障

怎么做

个人认为这篇讲的很好:

https://www.cnblogs.com/George1994/p/7821357.html

注意

debug树链剖分对于我来说真是个痛苦的过程,查了近一个小时错才查出来.

首先你要知道线段树上序列是什么?

他们是\(dfs\_2\)中的每个树节点的\(dfs\)顺序存在\(dfn[]\)中,\(rnk[]\)则记录对应\(dfn[]\)对应的节点编号,这点千万不要搞错,尤其在单点操作时极其容易忽略

build函数

  void build(int now,int l,int r){
  if(l==r){
  	mx[now]=sum[now]=w[rnk[l]];//注意是rnk[l]
  	return ;
  }
  int mid=(l+r)>>1;
  build(now<<1,l,mid);
  build(now<<1|1,mid+1,r);
  sum[now]=sum[now<<1]+sum[now<<1|1];
  mx[now]=max(mx[now<<1],mx[now<<1|1]);
  return ;
  }
 

必要的操作(一定要检查是否写了)

  dep[1]=1,fa[1]=0;//假设root是1
  dfs_1(1);
  dfs_2(1,1);
  build(1,1,n);
  

例题1:

https://www.luogu.org/problemnew/show/P2590

代码:请戳这里

简要题解: 无

例题2:

https://www.luogu.org/problemnew/show/P3384

代码: 请戳这里

简要题解: 无

例题3:

https://www.luogu.org/problemnew/show/P3950

代码及题解:

https://www.cnblogs.com/Rye-Catcher/p/9351619.html

例题4:

https://www.luogu.org/problemnew/show/P4092#sub

这道题比较有意思,题解中找目标所在重链然后倍增的思路在今年NOI中可以运用

代码及题解:

https://www.cnblogs.com/Rye-Catcher/p/9275770.html

例题5:

查了好久的错...

https://www.luogu.org/problemnew/show/P2146

代码: 请戳这里

简要题解:区间覆盖

posted @ 2018-07-04 22:55  Rye_Catcher  阅读(199)  评论(0编辑  收藏  举报