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. C# 整形、双精度浮点型、字符串与字节型的相互转化

    整形.双精度浮点型.字符串与字节型的相互转化,如下 using System; using System.Collections.Generic; using System.Linq; using S ...

  2. linux普通用户权限设置为超级用户权限方法、sudo不用登陆密码

    以用户zato为例 普通用户权限设置为超级用户权限 进入有超级用户权限的账号 添加文件可写(w)权限 sudo chmod u+x /etc/sudoers 编辑/etc/sudoers文件 添加语句 ...

  3. java中的类和对象

    Java中的类是一个模板,它用于描述一类对象的行为和状态. 对象则是类中的一个实例,对象有状态(属性)和行为(方法).例如一条狗就是一个对象,他的状态就是他的颜色,名字,品种:他的行为就是叫,摇尾巴, ...

  4. log file switch (checkpoint incomplete)

    接手了一个新交接的库,alert日志频繁报告log file switch (checkpoint incomplete)事件 oracle文档解释: Waiting for a log switch ...

  5. mini install centOS log

    no ifconfig yum install net-tools ------------------------------------------------------------------ ...

  6. First learning operation system

    1,操作系统负责管理硬件资源,为应用程序的开发执行提供基础 2,用户空间包括应用程序,只能通过调用系统调用访问硬件,无法访问更小粒度功能 3,设备驱动程序函数和内核子系统的函数对用户不可见 4,操作系 ...

  7. 解决plsql工具不能用中文字进行模糊匹配

    今天碰到了 select * from table1 t where t.name like '模块a' 查不出数据 而select * from table1 t where t.name like ...

  8. java 笔记(2) —— 内部类的作用

    一.内部类简介 个人觉得内部类没多少研究价值,GUI中的事件响应算是非常典型的应用了. Java内部类其实在J2EE编程中使用较少,不过在窗口应用编程中特别常见,主要用来事件的处理.其实,做非GUI编 ...

  9. 刨根问底U3D---关于Delegate的方方面面

    我是否需要阅读这篇文章 Code1: private delegate void BloodNumDelegate (); public delegate void ExpNumChangeDeleg ...

  10. 01分数规划POJ2976(简单模板题)

    Dropping tests Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7276   Accepted: 2523 De ...