http://poj.org/problem?id=2763

题意:给出 n 个点, n-1 条带权边, 询问是询问 s 到 v 的权值, 修改是修改存储时候的第 i 条边的权值。

思路:树链剖分之修改边权。边权的修改, 与点权修改不同的地方在于, 线段树中存的点是边,其中每条边边是以 儿子 的时间戳来记录的。例如: u -> v , dep[u] < dep[v], 说明 u 是 v 的父亲,所以这条边在线段树中的编号就是以 tid[v].

 #include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
#define N 100005
#define INF 0x3f3f3f3f
#define lson rt<<1, l, m
#define rson rt<<1|1, m+1, r
struct node
{
int v, w, next;
}edge[N*];
int head[N], tot;
int time, tid[N], fa[N], rak[N], son[N], dep[N], size[N], top[N];
int tree[N<<];
int e[N][]; /*
树链剖分: 边权的修改, 与点权修改不同的地方在于, 线段树中存的点是边,
其中每条边边是以 儿子 的时间戳来记录的
例如: u -> v , dep[u] < dep[v], 说明 u 是 v 的父亲,
所以这条边在线段树中的编号就是以 tid[v] 的形式来存储.
*/ void init()
{
memset(head, -, sizeof(head));
memset(son, -, sizeof(son));
memset(fa, , sizeof(fa));
time = tot = ;
} void add(int u, int v, int w)
{
edge[tot].next = head[u]; edge[tot].v = v; edge[tot].w = w; head[u] = tot++;
} void dfs1(int u, int f, int d)
{
size[u] = ;
dep[u] = d;
fa[u] = f;
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v;
if(v == f) continue;
dfs1(v, u, d + );
size[u] += size[v];
if(son[u] == - || size[son[u]] < size[v])
son[u] = v;
}
} void dfs2(int u, int f)
{
tid[u] = ++time;
top[u] = f;
rak[time] = u;
if(son[u] == -) return ;
dfs2(son[u], f);
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].v;
if(v != son[u] && v != fa[u]) {
dfs2(v, v);
}
}
} void build(int rt, int l, int r)
{
tree[rt] = ;
if(l == r) return ;
int m = (l + r) >> ;
build(lson); build(rson);
} void pushup(int rt)
{
tree[rt] = tree[rt<<] + tree[rt<<|];
} void update(int rt, int l, int r, int id, int w)
{
if(l == id && r == id) {
tree[rt] = w;
return ;
}
if(l == r) return ;
int m = (l + r) >> ;
if(id <= m) update(lson, id, w);
else update(rson, id, w);
pushup(rt);
} long long query(int rt, int l, int r, int L, int R)
{
long long ans = ;
if(L <= l && r <= R) {
ans += tree[rt];
return ans;
}
int m = (l + r) >> ;
if(L <= m) ans += query(lson, L, R);
if(m < R) ans += query(rson, L, R);
return ans;
} long long change(int u, int v)
{
long long ans = ;
int tp1 = top[u], tp2 = top[v];
while(top[u] != top[v]) {
if(dep[top[u]] < dep[top[v]]) swap(u, v);
ans += query(, , time, tid[top[u]], tid[u]);
u = fa[top[u]];
}
if(dep[u] > dep[v]) swap(u, v);
if(u == v) return ans; // 如果是同一个点, 就不能继续询问了
ans += query(, , time, tid[son[u]], tid[v]);
return ans;
} int main()
{
int n, q, s;
scanf("%d%d%d", &n, &q, &s);
init();
for(int i = ; i < n; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
e[i][] = u, e[i][] = v, e[i][] = w;
add(u, v, w); add(v, u, w);
}
dfs1(s, s, );
dfs2(s, s);
build(, , time);
for(int i = ; i < n; i++) {
if(dep[e[i][]] > dep[e[i][]]) swap(e[i][], e[i][]);
update(, , time, tid[e[i][]], e[i][]);
}
for(int i = ; i < q; i++) {
int o, a, b;
scanf("%d", &o);
if(o == ) {
scanf("%d%d", &a, &b);
update(, , time, tid[e[a][]], b);
} else {
scanf("%d", &a);
long long ans = change(s, a);
s = a;
printf("%lld\n", ans);
}
}
return ;
} /*
4 4 1
1 2 1
2 3 2
1 4 1
0 2
1 2 3
0 3
0 4
*/

POJ 2763:Housewife Wind(树链剖分)的更多相关文章

  1. POJ - 2763 Housewife Wind (树链剖分/ LCA+RMQ+树状数组)

    题意:有一棵树,每条边给定初始权值.一个人从s点出发.支持两种操作:修改一条边的权值:求从当前位置到点u的最短路径. 分析:就是在边可以修改的情况下求树上最短路.如果不带修改的话,用RMQ预处理LCA ...

  2. POJ 2763 Housewife Wind (树链剖分 有修改单边权)

    题目链接:http://poj.org/problem?id=2763 n个节点的树上知道了每条边权,然后有两种操作:0操作是输出 当前节点到 x节点的最短距离,并移动到 x 节点位置:1操作是第i条 ...

  3. poj 2763 Housewife Wind : 树链剖分维护边 O(nlogn)建树 O((logn)²)修改与查询

    /** problem: http://poj.org/problem?id=2763 **/ #include<stdio.h> #include<stdlib.h> #in ...

  4. poj 2763 Housewife Wind(树链拆分)

    id=2763" target="_blank" style="">题目链接:poj 2763 Housewife Wind 题目大意:给定一棵 ...

  5. POJ 2763 Housewife Wind 树链拋分

    一.前言 这破题WA了一天,最后重构还是WA,最后通过POJ讨论版得到的数据显示,我看上去是把某个变量写错了..于是,还是低级错误背锅啊....代码能力有待进一步提升2333333 二.题意 某家庭主 ...

  6. POJ2763 Housewife Wind 树链剖分 边权

    POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...

  7. poj 2763(RMQ+BIT\树链剖分)

    传送门:Problem 2763 https://www.cnblogs.com/violet-acmer/p/9686774.html 题意: 一对夫妇居住在xx村庄,小屋之间有双向可达的道路,不会 ...

  8. POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )

    POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...

  9. POJ 2763 Housewife Wind LCA转RMQ+时间戳+线段树成段更新

    题目来源:POJ 2763 Housewife Wind 题意:给你一棵树 2种操作0 x 求当前点到x的最短路 然后当前的位置为x; 1 i x 将第i条边的权值置为x 思路:树上两点u, v距离为 ...

  10. poj 2763 Housewife Wind (树链剖分)

    题目链接:http://poj.org/problem?id=2763 题意: 给定一棵含n个结点的树和树的边权,共有q次操作,分为两种 0 c :求从位置s到c的距离,然后s变成c 1 a b:把第 ...

随机推荐

  1. [ROS]1 小乌龟

    对于一个新新新手,Linux,ROS都要学习.安装ROS真的很讨厌了,于是采用易科机器人实验室的ubuntu12.04-amd64-ros-exbot-h2-140520版本. 测试一下小乌龟节点.主 ...

  2. [转载]Oracle修改表空间大小

    Oracle修改表空间大小 使用Oracle10g建立数据库后,向数据库中导入了部分数据,第二天继续向数据库中导入数据表时发生错误: 查了很多资料发现原来是Oracle表空间限制,导致无法继续导入数据 ...

  3. Linux 安装php

    安装libxml2 下载解压 libxml2-2.6.32.tar.gz 安装 ./configure --prefix=/usr/local/libxml2makesudo make install ...

  4. javaScript中的数据类型

    一.综述 javaScript中的数据类型分为两类: 简单类型:Boolean,Number,String 引用类型:Object 其他:undefined代表变量没有初始化,null代表引用类型为空 ...

  5. error MIDL2311 : statements outside library block are illegal in mktyplib compatability mode

    解决办法: 1. Do not use the /mktyplib203 switch unless you have to deal with legacy code dating back to ...

  6. memwatch内存泄露检测工具

    工具介绍 官网 http://www.linkdata.se/sourcecode/memwatch/ 其功能如下官网介绍,挑选重点整理: 1. 号称功能: 内存泄露检测 (检测未释放内存, 即 动态 ...

  7. [转]那些年我还不懂:IList,ICollection,IEnumerable,IEnumerator,IQueryable

    1.首先看一个简单的例子 int[] myArray = { 1, 32, 43, 343 }; IEnumerator myie = myArray.GetEnumerator(); myie.Re ...

  8. linix container & cgroup note

    1,Containers can run instructions native to the core CPU without any special interpretation mechanis ...

  9. 使用jquery的小记

    随便写点 1.给span这种标签赋值  不能用$("#id").val("abc"); 因为这种标签没有value属性 而应该用$("#id" ...

  10. jquery网址

    各种分布图的插件:http://echarts.baidu.com/demo.html