树链剖分学习

来源:互联网 发布:怎么复制淘宝店铺链接 编辑:程序博客网 时间:2024/05/20 00:12

树链剖分

看了http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html学习了树链剖分

适用于在树上的路径操作。

关键在于重链的构造,把它表示到了数据结构上的连续区间,降低了复杂度。


主要操作步骤实际上有三个部分

1: 构造重链

2: 如何维护数据

3: 分解为轻重链的查询与修改


#include <iostream>#include <algorithm>#include <cstdio>#include <queue>#define N 10010using namespace std;struct node{int e,next,w;}K[N*2];int now;int num;int son[N],_hash[N],deep[N],head[N],fa[N],sum[N],top[N];void add(int x,int y,int w){K[now].e=y;K[now].w=w;K[now].next=head[x];head[x]=now++;return ;}int dfs(int x,int f){fa[x]=f;son[x]=0,sum[x]=1;for(int i=head[x];~i;i=K[i].next){int to=K[i].e;if(to==f)continue;deep[to]=deep[x]+1;dfs(to,x);sum[x]+=sum[to];if(sum[to]>sum[son[x]]||son[x]==0)son[x]=to;//重子的选择}return ;}void build_tree(int x,int f){_hash[x]=num++;//映射结点到线段树上top[x]=f; //重链端点if(son[x]!=0)build_tree(son[x],f);for(int i=head[x];~i;i=K[i].next){int to=K[i].e;if(son[x]!=to)build_tree(to,to);}return ;}void modify(int x,int y,int z){<span style="white-space:pre"></span>while(top[x]!=top[y]){                //printf("f1=%d,f2=%d\n",f1,f2);                if(deep[top[x]]<deep[top[y]])swap(x,y);                l=_hash[x],r=_hash[top[x]];//r<l<span style="white-space:pre"></span>//修改r,l                x=fa[top[x]];            }                l=_hash[x],r=_hash[y];                if(l>r)swap(l,r);            //修改l,r}




HDU5029 ( Relief grain )  




0 0
原创粉丝点击