您的位置:首页 > Web前端

poj 2763 Housewife Wind 边权的树链剖分

2015-09-08 17:33 477 查看
//	poj 2763 Housewife Wind 边权的树链剖分
//	
//	题目意思很清楚,关于边权的树链剖分,首先
//	肯定是先把链剖分好啦,然后就是将边权转化
//	成离根节点较远的点的权值即可.单点更新,
//	区间求和,注意,莫要重复计算哟,这题还有需要
//	研究的地方,继续加油吧~~~
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define cls(x,a) memset(x,(a),sizeof(x))
using namespace std;

const int maxn = 100000 + 8;
int n,q,s;

int head[maxn];

int id;
int idx[maxn];
int father[maxn];
int siz[maxn];
int son[maxn];
int dep[maxn];
int rk[maxn];
int top[maxn];

int num;

struct Node{
	int to;
	int next;
	
	Node(){

	}

	Node(int a,int b):to(a),next(b){

	}
}edges[maxn<<1];

void add_edges(int u,int v){
	edges[num] = Node(v,head[u]);
	head[u] = num++;
}

struct edge{
	int u;
	int v;
	int w;
	edge(){

	}
	edge(int u,int v,int w):u(u),v(v),w(w){

	}
}e[maxn];

void dfs(int u,int fa,int d){
	siz[u] = 1;
	dep[u] = d;
	son[u] = 0;
	father[u] = fa;

	for (int i = head[u];i != -1; i = edges[i].next){
		int v = edges[i].to;

		if (v == fa)
			continue;
		
		dfs(v,u,d+1);
		siz[u] += siz[v];

		if (siz[son[u]] < siz[v]){
			son[u] = v;
		}
	}
}

void dfs(int u,int tp){
	top[u] = tp;
	idx[u] = id++;
	rk[idx[u]] = u;

	if (son[u])
		dfs(son[u],tp);

	for (int i = head[u];i != -1;i = edges[i].next){
		int v = edges[i].to;

		if (v == father[u] || v == son[u])
			continue;

		dfs(v,v);
	}
}

#define lson(x) (x<<1)
#define rson(x) (x<<1|1)

int seg[maxn<<2];
int val[maxn];

void push_up(int ro){
	seg[ro] = seg[lson(ro)] + seg[rson(ro)];
}

void build(int ro,int L,int R){
	if (L == R){
		seg[ro] = val[L];
		return ;
	}

	int M = (L+R)>>1;

	build(lson(ro),L,M);
	build(rson(ro),M+1,R);
	push_up(ro);
}

int ql,qr,delta;

void update(int ro,int L,int R){
	if (L == R){
		seg[ro] = delta;
		return ;
	}

	int M = (L + R) >> 1;

	if (ql <= M)	update(lson(ro),L,M);
	else	update(rson(ro),M+1,R);
	push_up(ro);
}

int query(int ro,int L,int R){
	if (ql<= L && R<= qr){
		return seg[ro];
	}

	int M = (L + R) >> 1;

	int ans = 0;

	if (ql <= M)	ans += query(lson(ro),L,M);
	if (M < qr)		ans += query(rson(ro),M+1,R);
	return ans;
}

int get(int u,int v){
	int p = top[u],q = top[v];
	
	int ans = 0;

	while(p != q){
		if (dep[p] < dep[q]){
			swap(u,v);
			swap(p,q);
		}
	
		ql = idx[p];
		qr = idx[u];

		ans += query(1,1,n);
		u = father[p];
		p = top[u];
	}

	if (u == v)
		return ans;

	if (dep[u] > dep[v]){
		swap(u,v);
	}

	ql = idx[son[u]];
	qr = idx[v];

	ans += query(1,1,n);

	return ans;
}

void input(){
	cls(head,-1);
	num = 0;
	id = 1;
	for (int i=1;i<n;i++){
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		e[i] = edge(u,v,w);
		add_edges(u,v);
		add_edges(v,u);
	}
	dfs(1,0,0);
	dfs(1,1);

	for (int i=1;i<n;i++){
		if (dep[e[i].u] < dep[e[i].v])
			swap(e[i].u,e[i].v);

		val[idx[e[i].u]] = e[i].w;
	}
	build(1,1,n);
	for (int i=1;i<=q;i++){
		int k,u,v;
		scanf("%d",&k);
		if (k==0){
			scanf("%d",&u);
			printf("%d\n",get(s,u));
			s = u;
		}else {
			scanf("%d%d",&u,&v);
			ql = idx[e[u].u];
			delta = v;
			update(1,1,n);
		}
	}

}

int main(){
	//freopen("1.txt","r",stdin);
	while(scanf("%d%d%d",&n,&q,&s)!=EOF){
		input();
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: