POJ 2736 Housewife Wind(树链剖分)

POJ 2763 Housewife Wind

题目链接

就树链剖分。。不过这题坑ector啊!, vector居然超时

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

#define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)

typedef long long ll;
const int N = 100005;

int dep[N], sz[N], son[N], fa[N], top[N], id[N], idx, val[N];

int n, q, s;
struct Edge {
	int u, v, val;
	void read() {
		scanf("%d%d%d", &u, &v, &val);
	}
} e[N];

int first[N], next[N * 2], vv[N * 2], en;

void add_Edge(int u, int v) {
	vv[en] = v;
	next[en] = first[u];
	first[u] = en++;
}

void dfs1(int u, int f, int d) {
	dep[u] = d;
	fa[u] = f;
	sz[u] = 1;
	son[u] = 0;
	for (int i = first[u]; i + 1; i = next[i]) {
		int v = vv[i];
		if (v == f) continue;
		dfs1(v, u, d + 1);
		sz[u] += sz[v];
		if (sz[son[u]] < sz[v])
			son[u] = v;
	}
}

void dfs2(int u, int tp) {
	top[u] = tp;
	id[u] = ++idx;
	if (son[u]) dfs2(son[u], tp);
	for (int i = first[u]; i + 1; i = next[i]) {
		int v = vv[i];
		if (v == fa[u] || v == son[u]) continue;
		dfs2(v, v);
	}
}

struct Node {
	int l, r;
	ll v;
} node[N * 4];

void pushup(int x) {
	node[x].v = node[lson(x)].v + node[rson(x)].v;
}

void build(int l, int r, int x = 0) {
	if (l > r) return;
	node[x].l = l; node[x].r = r;
	if (l == r) {
		node[x].v = val[l];
		return;
	}
	int mid = (l + r) / 2;
	build(l, mid, lson(x));
	build(mid + 1, r, rson(x));
	pushup(x);
}

void add(int v, int val, int x = 0) {
	if (node[x].l == node[x].r) {
		node[x].v = val;
		return;
	}
	int mid = (node[x].l + node[x].r) / 2;
	if (v <= mid) add(v, val, lson(x));
	if (v > mid) add(v, val, rson(x));
	pushup(x);
}

ll query(int l, int r, int x = 0) {
	if (node[x].l >= l && node[x].r <= r) {
		return node[x].v;
	}
	int mid = (node[x].l + node[x].r) / 2;
	ll ans = 0;
	if (l <= mid) ans += query(l, r, lson(x));
	if (r > mid) ans += query(l, r, rson(x));
	return ans;
}

ll gao(int u, int v) {
	int tp1 = top[u], tp2 = top[v];
	ll ans = 0;
	while (tp1 != tp2) {
		if (dep[tp1] < dep[tp2]) {
			swap(tp1, tp2);
			swap(u, v);
		}
		ans += query(id[tp1], id[u]);
		u = fa[tp1];
		tp1 = top[u];
	}
	if (u == v) return ans;
	if (dep[u] > dep[v]) swap(u, v);
	ans += query(id[son[u]], id[v]);
	return ans;
}

int main() {
	while (~scanf("%d%d%d", &n, &q, &s)) {
		idx = -1;
		en = 0;
		memset(first, -1, sizeof(first));
		for (int i = 1; i < n; i++) {
			e[i].read();
			add_Edge(e[i].u, e[i].v);
			add_Edge(e[i].v, e[i].u);
		}
		dfs1(1, 0, 1);
		dfs2(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[id[e[i].u]] = e[i].val;
		}
		build(1, idx);
		int ty, a, b;
		while (q--) {
			scanf("%d%d", &ty, &a);
			if (ty == 0) {
				printf("%lld\n", gao(s, a));
				s = a;
			} else {
				scanf("%d", &b);
				add(id[e[a].u], b);
			}
		}
	}
	return 0;
}
时间: 2024-10-12 22:23:48

POJ 2736 Housewife Wind(树链剖分)的相关文章

POJ 2763 Housewife Wind (树链剖分+线段树)

题目链接:POJ 2763 Housewife Wind 题意:抽象出来就是 一棵已知节点之间的边权,两个操作,1·修改边权,2·询问两个节点之间的边权和. AC代码: #include <string.h> #include <stdio.h> #include <algorithm> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int

POJ 2763 Housewife Wind (树链剖分)

题目地址:POJ 2763 还是树链剖分模板题...不多说.. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h>

poj 2763 Housewife Wind : 树链剖分维护边 O(nlogn)建树 O((logn)&#178;)修改与查询

1 /** 2 problem: http://poj.org/problem?id=2763 3 **/ 4 #include<stdio.h> 5 #include<stdlib.h> 6 #include<string.h> 7 #include<vector> 8 using namespace std; 9 10 const int MAXN = 100005; 11 12 template <typename T> 13 class

POJ 2763 Housewife Wind 树链拋分

一.前言 这破题WA了一天,最后重构还是WA,最后通过POJ讨论版得到的数据显示,我看上去是把某个变量写错了..于是,还是低级错误背锅啊....代码能力有待进一步提升2333333 二.题意 某家庭主妇住在一棵树上,他的若干个孩子在树的若干个节点上有分布,主妇同学需要从某给定节点出发,飞到树上的制定节点,在过程中,边权可能会发生改变,问从当前节点到指定节点的边权和. 三.解法 树链拋分,点更新查区间. // #include<bits/stdc++.h> #include<iostrea

poj2763--Housewife Wind(树链剖分+线段树)

Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 6898   Accepted: 1742 Description After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy life. People in XX Village lived in beautif

poj 3237 Tree(树链剖分,线段树)

Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 7268   Accepted: 1969 Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with

POJ 3723 Tree(树链剖分)

POJ 3237 Tree 题目链接 就多一个取负操作,所以线段树结点就把最大和最小值存下来,每次取负的时候,最大和最小值取负后,交换即可 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 10005; const int INF = 0x3f3f3f3f; int dep[N],

Poj2763Housewife Wind树链剖分

边查询,点更新的模板题. #include<iostream> #include<cstdio> #include<cstring> #include<map> #include<vector> #include<stdlib.h> using namespace std; typedef long long LL; const int maxn = 222222; struct Node { int to;int next; }e[

poj 2763 Housewife Wind(树链剖分+单点查询+区间修改)

题目链接:http://poj.org/problem?id=2763 题意:给一个数,边之间有权值,然后两种操作,第一种:求任意两点的权值和,第二,修改树上两点的权值. 题解:简单的树链剖分. #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int M = 1e5 + 10; struct Edge { int v , next; }edge[M &