树链剖分学习

树链剖分

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

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

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


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

1: 构造重链

2: 如何维护数据

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


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#define N 10010
using 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 )  




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值